Initial local backup snapshot
This commit is contained in:
commit
acd9e14ba5
367 changed files with 118038 additions and 0 deletions
161
server/logisticsSettings.ts
Normal file
161
server/logisticsSettings.ts
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import * as db from "./db";
|
||||
import {
|
||||
materialEventInventory,
|
||||
materialEventItems,
|
||||
materialEventReplacementValues,
|
||||
type MaterialEventItemKey,
|
||||
} from "@shared/materialEvent";
|
||||
|
||||
export const LOGISTICS_SETTINGS_KEY = "system.logistics.settings";
|
||||
|
||||
export type LogisticsSettings = {
|
||||
materialReturnLeadDays: number;
|
||||
materialReturnGraceDays: number;
|
||||
inventory: Record<MaterialEventItemKey, number | null>;
|
||||
replacementValues: Record<MaterialEventItemKey, number | null>;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
|
||||
export const defaultLogisticsSettings: Omit<LogisticsSettings, "updatedAt"> = {
|
||||
materialReturnLeadDays: 4,
|
||||
materialReturnGraceDays: 3,
|
||||
inventory: {
|
||||
...materialEventInventory,
|
||||
},
|
||||
replacementValues: {
|
||||
...materialEventReplacementValues,
|
||||
},
|
||||
};
|
||||
|
||||
function clampWholeNumber(value: unknown, fallback: number, min: number, max: number) {
|
||||
const parsed = Number.parseInt(String(value ?? ""), 10);
|
||||
if (!Number.isFinite(parsed)) return fallback;
|
||||
return Math.min(max, Math.max(min, parsed));
|
||||
}
|
||||
|
||||
function sanitizeInventory(rawInventory: unknown) {
|
||||
const nextInventory = { ...defaultLogisticsSettings.inventory } as Record<MaterialEventItemKey, number | null>;
|
||||
|
||||
if (!rawInventory || typeof rawInventory !== "object") {
|
||||
return nextInventory;
|
||||
}
|
||||
|
||||
for (const item of materialEventItems) {
|
||||
const rawValue = (rawInventory as Record<string, unknown>)[item.key];
|
||||
if (rawValue === null || rawValue === "") {
|
||||
nextInventory[item.key] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
const parsed = Number.parseInt(String(rawValue ?? ""), 10);
|
||||
if (Number.isFinite(parsed) && parsed >= 0) {
|
||||
nextInventory[item.key] = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
return nextInventory;
|
||||
}
|
||||
|
||||
function sanitizeReplacementValues(rawReplacementValues: unknown) {
|
||||
const nextReplacementValues = {
|
||||
...defaultLogisticsSettings.replacementValues,
|
||||
} as Record<MaterialEventItemKey, number | null>;
|
||||
|
||||
if (!rawReplacementValues || typeof rawReplacementValues !== "object") {
|
||||
return nextReplacementValues;
|
||||
}
|
||||
|
||||
for (const item of materialEventItems) {
|
||||
const rawValue = (rawReplacementValues as Record<string, unknown>)[item.key];
|
||||
if (rawValue === null || rawValue === "") {
|
||||
nextReplacementValues[item.key] = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
const parsed = Number.parseInt(String(rawValue ?? ""), 10);
|
||||
if (Number.isFinite(parsed) && parsed >= 0) {
|
||||
nextReplacementValues[item.key] = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
return nextReplacementValues;
|
||||
}
|
||||
|
||||
function sanitizeLogisticsSettings(rawValue: unknown, updatedAt: string | null): LogisticsSettings {
|
||||
const source = rawValue && typeof rawValue === "object" ? rawValue as Record<string, unknown> : {};
|
||||
|
||||
return {
|
||||
materialReturnLeadDays: clampWholeNumber(
|
||||
source.materialReturnLeadDays,
|
||||
defaultLogisticsSettings.materialReturnLeadDays,
|
||||
1,
|
||||
30
|
||||
),
|
||||
materialReturnGraceDays: clampWholeNumber(
|
||||
source.materialReturnGraceDays,
|
||||
defaultLogisticsSettings.materialReturnGraceDays,
|
||||
0,
|
||||
30
|
||||
),
|
||||
inventory: sanitizeInventory(source.inventory),
|
||||
replacementValues: sanitizeReplacementValues(source.replacementValues),
|
||||
updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getLogisticsSettings(): Promise<LogisticsSettings> {
|
||||
const record = await db.getPortalSettingRecord(LOGISTICS_SETTINGS_KEY);
|
||||
if (!record?.valeur) {
|
||||
return {
|
||||
...defaultLogisticsSettings,
|
||||
updatedAt: null,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(record.valeur);
|
||||
return sanitizeLogisticsSettings(parsed, record.updatedAt?.toISOString?.() || null);
|
||||
} catch {
|
||||
return {
|
||||
...defaultLogisticsSettings,
|
||||
updatedAt: record.updatedAt?.toISOString?.() || null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveLogisticsSettings(input: {
|
||||
materialReturnLeadDays?: number;
|
||||
materialReturnGraceDays?: number;
|
||||
inventory?: Partial<Record<MaterialEventItemKey, number | null>>;
|
||||
replacementValues?: Partial<Record<MaterialEventItemKey, number | null>>;
|
||||
}) {
|
||||
const current = await getLogisticsSettings();
|
||||
const next = sanitizeLogisticsSettings(
|
||||
{
|
||||
materialReturnLeadDays: input.materialReturnLeadDays ?? current.materialReturnLeadDays,
|
||||
materialReturnGraceDays: input.materialReturnGraceDays ?? current.materialReturnGraceDays,
|
||||
inventory: {
|
||||
...current.inventory,
|
||||
...(input.inventory || {}),
|
||||
},
|
||||
replacementValues: {
|
||||
...current.replacementValues,
|
||||
...(input.replacementValues || {}),
|
||||
},
|
||||
},
|
||||
new Date().toISOString()
|
||||
);
|
||||
|
||||
await db.setPortalSetting(
|
||||
LOGISTICS_SETTINGS_KEY,
|
||||
JSON.stringify({
|
||||
materialReturnLeadDays: next.materialReturnLeadDays,
|
||||
materialReturnGraceDays: next.materialReturnGraceDays,
|
||||
inventory: next.inventory,
|
||||
replacementValues: next.replacementValues,
|
||||
}),
|
||||
"Réglages logistiques globaux du portail"
|
||||
);
|
||||
|
||||
return getLogisticsSettings();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue