Fix invoice preview i18n release gate (#255)

Use a statically discoverable invoice-preview translation key while preserving the off-period fallback.
This commit is contained in:
Jeppe B
2026-08-03 14:12:12 +02:00
committed by GitHub
parent f995440098
commit 60dff74507
@@ -38,9 +38,8 @@ export const normalizeInvoiceCollectionActionPreview = (
): InvoiceCollectionActionPreview => { ): InvoiceCollectionActionPreview => {
const preview = value && typeof value === "object" ? (value as Record<string, any>) : {}; const preview = value && typeof value === "object" ? (value as Record<string, any>) : {};
const summary = preview.summary && typeof preview.summary === "object" ? preview.summary : {}; const summary = preview.summary && typeof preview.summary === "object" ? preview.summary : {};
const impact = preview.off_period_impact && typeof preview.off_period_impact === "object" const impact =
? preview.off_period_impact preview.off_period_impact && typeof preview.off_period_impact === "object" ? preview.off_period_impact : {};
: {};
const options = preview.options && typeof preview.options === "object" ? preview.options : {}; const options = preview.options && typeof preview.options === "object" ? preview.options : {};
const changes = [ const changes = [
...asArray(preview.changes), ...asArray(preview.changes),
@@ -53,26 +52,25 @@ export const normalizeInvoiceCollectionActionPreview = (
return { return {
previewId: String(preview.preview_id ?? ""), previewId: String(preview.preview_id ?? ""),
confirmationPhrase: String(preview.confirmation_phrase ?? ""), confirmationPhrase: String(preview.confirmation_phrase ?? ""),
collectionCount: finiteNumber( collectionCount:
summary.collection_count ?? summary.collections ?? asArray(preview.invoice_collection_ids).length ?? fallbackCollectionCount finiteNumber(
) || fallbackCollectionCount, summary.collection_count ??
summary.collections ??
asArray(preview.invoice_collection_ids).length ??
fallbackCollectionCount
) || fallbackCollectionCount,
changedCount: finiteNumber(summary.changed_count ?? summary.order_items ?? summary.orders_to_move), changedCount: finiteNumber(summary.changed_count ?? summary.order_items ?? summary.orders_to_move),
skippedCount: finiteNumber(summary.skipped_count), skippedCount: finiteNumber(summary.skipped_count),
targetInvoiceCollectionId: positiveInteger( targetInvoiceCollectionId: positiveInteger(
preview.target_invoice_collection_id preview.target_invoice_collection_id ??
?? options.target_invoice_collection_id options.target_invoice_collection_id ??
?? summary.target_invoice_collection_id summary.target_invoice_collection_id
), ),
offPeriodOrderCount: finiteNumber( offPeriodOrderCount: finiteNumber(
impact.order_count impact.order_count ?? impact.orders ?? summary.off_period_order_count ?? asArray(preview.off_period_orders).length
?? impact.orders
?? summary.off_period_order_count
?? asArray(preview.off_period_orders).length
), ),
offPeriodTotalNetAmount: finiteNumber( offPeriodTotalNetAmount: finiteNumber(
impact.total_net_amount impact.total_net_amount ?? impact.amount ?? summary.off_period_total_net_amount
?? impact.amount
?? summary.off_period_total_net_amount
), ),
blockers: asArray(preview.blockers), blockers: asArray(preview.blockers),
changes, changes,
@@ -80,11 +78,6 @@ export const normalizeInvoiceCollectionActionPreview = (
}; };
}; };
const translated = (t: Translate, key: string, params: Record<string, unknown>, fallback: string) => {
const value = t(key, params);
return value === key ? fallback : value;
};
const concreteChangeLabel = (change: Record<string, any>, t: Translate) => { const concreteChangeLabel = (change: Record<string, any>, t: Translate) => {
if (change.message) { if (change.message) {
return String(change.message); return String(change.message);
@@ -125,6 +118,18 @@ export const renderInvoiceCollectionActionPreviewHtml = ({
t: Translate; t: Translate;
formatCurrency?: (value: number) => string; formatCurrency?: (value: number) => string;
}) => { }) => {
const translateOffPeriodImpact = () => {
const key = "invoicing_period.invoice_collection_actions.preview.off_period_impact";
const value = t("invoicing_period.invoice_collection_actions.preview.off_period_impact", {
count: preview.offPeriodOrderCount,
amount: formatCurrency(preview.offPeriodTotalNetAmount),
});
return value === key
? `${preview.offPeriodOrderCount} orders outside the selected period · ${formatCurrency(
preview.offPeriodTotalNetAmount
)}`
: value;
};
const lines = [ const lines = [
t("invoicing_period.invoice_collection_actions.preview.collections", { count: preview.collectionCount }), t("invoicing_period.invoice_collection_actions.preview.collections", { count: preview.collectionCount }),
t("invoicing_period.invoice_collection_actions.preview.changed", { count: preview.changedCount }), t("invoicing_period.invoice_collection_actions.preview.changed", { count: preview.changedCount }),
@@ -132,38 +137,51 @@ export const renderInvoiceCollectionActionPreviewHtml = ({
? [t("invoicing_period.invoice_collection_actions.preview.skipped", { count: preview.skippedCount })] ? [t("invoicing_period.invoice_collection_actions.preview.skipped", { count: preview.skippedCount })]
: []), : []),
...(preview.targetInvoiceCollectionId ...(preview.targetInvoiceCollectionId
? [t("invoicing_period.invoice_collection_actions.preview.merge_target", { id: preview.targetInvoiceCollectionId })] ? [
: []), t("invoicing_period.invoice_collection_actions.preview.merge_target", {
...(preview.offPeriodOrderCount > 0 id: preview.targetInvoiceCollectionId,
? [translated( }),
t, ]
"invoicing_period.invoice_collection_actions.preview.off_period_impact",
{ count: preview.offPeriodOrderCount, amount: formatCurrency(preview.offPeriodTotalNetAmount) },
`${preview.offPeriodOrderCount} orders outside the selected period · ${formatCurrency(preview.offPeriodTotalNetAmount)}`
)]
: []), : []),
...(preview.offPeriodOrderCount > 0 ? [translateOffPeriodImpact()] : []),
]; ];
const html = [ const html = [
`<p>${escapeInvoiceCollectionPreviewHtml(t( `<p>${escapeInvoiceCollectionPreviewHtml(
"invoicing_period.invoice_collection_actions.preview.requires_confirmation", t("invoicing_period.invoice_collection_actions.preview.requires_confirmation", {
{ phrase: preview.confirmationPhrase } phrase: preview.confirmationPhrase,
))}</p>`, })
`<ul class="has-text-left">${lines.map((line) => `<li>${escapeInvoiceCollectionPreviewHtml(line)}</li>`).join("")}</ul>`, )}</p>`,
`<ul class="has-text-left">${lines
.map((line) => `<li>${escapeInvoiceCollectionPreviewHtml(line)}</li>`)
.join("")}</ul>`,
]; ];
const changes = preview.changes.map((change) => concreteChangeLabel(change, t)).filter(Boolean).slice(0, 10); const changes = preview.changes
.map((change) => concreteChangeLabel(change, t))
.filter(Boolean)
.slice(0, 10);
if (changes.length > 0) { if (changes.length > 0) {
html.push(`<hr><p class="has-text-left has-text-weight-bold">${escapeInvoiceCollectionPreviewHtml( html.push(
t("invoicing_period.invoice_collection_actions.preview.affected_examples") `<hr><p class="has-text-left has-text-weight-bold">${escapeInvoiceCollectionPreviewHtml(
)}</p>`); t("invoicing_period.invoice_collection_actions.preview.affected_examples")
html.push(`<ul class="has-text-left">${changes.map((line) => `<li>${escapeInvoiceCollectionPreviewHtml(line)}</li>`).join("")}</ul>`); )}</p>`
);
html.push(
`<ul class="has-text-left">${changes
.map((line) => `<li>${escapeInvoiceCollectionPreviewHtml(line)}</li>`)
.join("")}</ul>`
);
} }
if (preview.blockers.length > 0) { if (preview.blockers.length > 0) {
html.push(`<hr><p class="has-text-left has-text-weight-bold has-text-danger">${escapeInvoiceCollectionPreviewHtml( html.push(
t("invoicing_period.invoice_collection_actions.preview.blockers") `<hr><p class="has-text-left has-text-weight-bold has-text-danger">${escapeInvoiceCollectionPreviewHtml(
)}</p>`); t("invoicing_period.invoice_collection_actions.preview.blockers")
html.push(`<ul class="has-text-left">${preview.blockers.map((blocker) => `<li>${escapeInvoiceCollectionPreviewHtml( )}</p>`
blocker.message || blocker.code );
)}</li>`).join("")}</ul>`); html.push(
`<ul class="has-text-left">${preview.blockers
.map((blocker) => `<li>${escapeInvoiceCollectionPreviewHtml(blocker.message || blocker.code)}</li>`)
.join("")}</ul>`
);
} }
return html.join(""); return html.join("");
}; };