Checkpoint: Ajout de la projection annuelle prévisionnel-réel dans Masse salariale : import contrôlé du fichier modèle 2025-2027, réel 2026 provenant uniquement des liasses Salaires, ajustements administrateur limités aux primes et évolutions de l'année courante/future, conservation des centimes, modèle de calcul testé et documentation. 72 tests, TypeScript et build validés.
This commit is contained in:
47
server/db.ts
47
server/db.ts
@@ -1,4 +1,4 @@
|
||||
import { and, asc, desc, eq } from "drizzle-orm";
|
||||
import { and, asc, desc, eq, inArray } from "drizzle-orm";
|
||||
import { drizzle } from "drizzle-orm/mysql2";
|
||||
import {
|
||||
capexLignes,
|
||||
@@ -478,12 +478,20 @@ export type MasseSalarialeImportRemuneration = Omit<
|
||||
export async function getMasseSalariale() {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
const [salaries, remunerations, evolutions] = await Promise.all([
|
||||
const [salaries, remunerations, evolutions, bulletinsMensuels] = await Promise.all([
|
||||
db.select().from(masseSalarialeSalaries).orderBy(asc(masseSalarialeSalaries.nom), asc(masseSalarialeSalaries.prenom)),
|
||||
db.select().from(masseSalarialeRemunerations),
|
||||
db.select().from(masseSalarialeEvolutions),
|
||||
db.select({
|
||||
annee: salairesLiasses.annee,
|
||||
mois: salairesLiasses.mois,
|
||||
matricule: salairesBulletins.matricule,
|
||||
brutMensuelCents: salairesBulletins.brutMensuelCents,
|
||||
brutAvecPrimesCents: salairesBulletins.brutAvecPrimesCents,
|
||||
primeAstreinteCents: salairesBulletins.primeAstreinteCents,
|
||||
}).from(salairesBulletins).innerJoin(salairesLiasses, eq(salairesBulletins.liasseId, salairesLiasses.id)),
|
||||
]);
|
||||
return { salaries, remunerations, evolutions };
|
||||
return { salaries, remunerations, evolutions, bulletinsMensuels };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -494,6 +502,7 @@ export async function getMasseSalariale() {
|
||||
export async function importMasseSalariale(
|
||||
salaries: MasseSalarialeImportSalarie[],
|
||||
remunerations: MasseSalarialeImportRemuneration[],
|
||||
options: { replaceForecastYears?: number[] } = {},
|
||||
) {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
@@ -520,6 +529,13 @@ export async function importMasseSalariale(
|
||||
.from(masseSalarialeSalaries);
|
||||
const idsByMatricule = new Map(persistedSalaries.map((row) => [row.matricule, row.id]));
|
||||
|
||||
if (options.replaceForecastYears?.length) {
|
||||
await tx.delete(masseSalarialeRemunerations).where(and(
|
||||
inArray(masseSalarialeRemunerations.annee, options.replaceForecastYears),
|
||||
eq(masseSalarialeRemunerations.nature, "previsionnel"),
|
||||
));
|
||||
}
|
||||
|
||||
for (const remuneration of remunerations) {
|
||||
const salarieId = idsByMatricule.get(remuneration.matricule);
|
||||
if (!salarieId) {
|
||||
@@ -535,6 +551,12 @@ export async function importMasseSalariale(
|
||||
salaireAnnuelBrutAvecPrimesCents: values.salaireAnnuelBrutAvecPrimesCents,
|
||||
salaireMensuelBrutHorsPrimesCents: values.salaireMensuelBrutHorsPrimesCents,
|
||||
tauxChargeBps: values.tauxChargeBps,
|
||||
nature: values.nature,
|
||||
primeAstreinteCents: values.primeAstreinteCents,
|
||||
primeCents: values.primeCents,
|
||||
evolutionCents: values.evolutionCents,
|
||||
primeReferenceCents: values.primeReferenceCents,
|
||||
evolutionReferenceCents: values.evolutionReferenceCents,
|
||||
periodeReference: values.periodeReference,
|
||||
statut: values.statut,
|
||||
source: values.source,
|
||||
@@ -545,6 +567,25 @@ export async function importMasseSalariale(
|
||||
});
|
||||
}
|
||||
|
||||
/** Met à jour uniquement les deux hypothèses qui peuvent être modifiées. */
|
||||
export async function setMasseSalarialeForecastAdjustments(input: {
|
||||
salarieId: number;
|
||||
annee: number;
|
||||
primeCents: number;
|
||||
evolutionCents: number;
|
||||
}) {
|
||||
const db = await getDb();
|
||||
if (!db) throw new Error("Database not available");
|
||||
await db.update(masseSalarialeRemunerations).set({
|
||||
primeCents: input.primeCents,
|
||||
evolutionCents: input.evolutionCents,
|
||||
}).where(and(
|
||||
eq(masseSalarialeRemunerations.salarieId, input.salarieId),
|
||||
eq(masseSalarialeRemunerations.annee, input.annee),
|
||||
eq(masseSalarialeRemunerations.nature, "previsionnel"),
|
||||
));
|
||||
}
|
||||
|
||||
/** Sauvegarde l'évolution manuelle sans dépendre de l'existence d'un bulletin. */
|
||||
export async function setMasseSalarialeEvolution(
|
||||
input: Pick<InsertMasseSalarialeEvolution, "salarieId" | "annee" | "evolutionSalarialeBps" | "createdBy">,
|
||||
|
||||
Reference in New Issue
Block a user