feat(documents): selected-custom-fields encode/decode helpers

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BOHA
2026-06-16 20:07:35 +02:00
parent 5551786da2
commit 2f084174df
2 changed files with 71 additions and 0 deletions

View File

@@ -46,3 +46,36 @@ export function decodeCustomFields(raw: string | null): {
return { custom_fields: [], field_order: [] };
}
}
/**
* Per-document selection of which COMPANY custom fields print on a PDF.
* Stored positionally (matching the `custom_<i>` keys the PDF builder emits)
* as a JSON array string, e.g. "[0,2]". Null/empty means "none selected".
*/
export function encodeSelectedCustomFields(indices: unknown): string | null {
const clean = normalizeIndices(indices);
return clean.length > 0 ? JSON.stringify(clean) : null;
}
/** Decode the stored selection (string OR defensive array) into a clean number[]. */
export function parseSelectedCustomFields(raw: unknown): number[] {
if (raw == null) return [];
if (Array.isArray(raw)) return normalizeIndices(raw);
if (typeof raw !== "string" || raw.trim() === "") return [];
try {
return normalizeIndices(JSON.parse(raw));
} catch {
// Malformed JSON in a selection column degrades to "none" (expected
// condition — a hand-edited/legacy row should never 500 a PDF render).
return [];
}
}
function normalizeIndices(input: unknown): number[] {
if (!Array.isArray(input)) return [];
const set = new Set<number>();
for (const v of input) {
if (typeof v === "number" && Number.isInteger(v) && v >= 0) set.add(v);
}
return [...set].sort((a, b) => a - b);
}