forked from Yara724/api
Merge pull request 'YARA-994 and fixed metal plate bug' (#191) from s.yahyaee/yara724-api:main into main
Reviewed-on: Yara724/api#191
This commit is contained in:
@@ -10205,6 +10205,18 @@ export class ClaimRequestManagementService {
|
|||||||
base: GetCaptureRequirementsV2ResponseDto,
|
base: GetCaptureRequirementsV2ResponseDto,
|
||||||
): GetCaptureRequirementsV2ResponseDto {
|
): GetCaptureRequirementsV2ResponseDto {
|
||||||
const skipMetalPlate = !!(blame as any)?.isMadeByFileMaker;
|
const skipMetalPlate = !!(blame as any)?.isMadeByFileMaker;
|
||||||
|
|
||||||
|
// For V4/V5 files strip metal-plate keys from the base response entirely
|
||||||
|
// so they never appear in any phase — the front-end should not show them.
|
||||||
|
if (skipMetalPlate) {
|
||||||
|
base = {
|
||||||
|
...base,
|
||||||
|
requiredDocuments: base.requiredDocuments.filter(
|
||||||
|
(d) => !OPTIONAL_CAPTURE_PHASE_DOC_KEYS_V4V5.includes(d.key as any),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const step = claimCase.workflow?.currentStep;
|
const step = claimCase.workflow?.currentStep;
|
||||||
const capturePartDone = this.claimV3StepCompleted(
|
const capturePartDone = this.claimV3StepCompleted(
|
||||||
claimCase,
|
claimCase,
|
||||||
|
|||||||
@@ -22,20 +22,18 @@ const LABEL_COLUMN_X = COLON_X + 10;
|
|||||||
|
|
||||||
function resolveFontFile(variant: "regular" | "bold"): string {
|
function resolveFontFile(variant: "regular" | "bold"): string {
|
||||||
const file =
|
const file =
|
||||||
variant === "bold"
|
variant === "bold" ? "Vazirmatn-Bold.ttf" : "Vazirmatn-Regular.ttf";
|
||||||
? "NotoKufiArabic-Bold.ttf"
|
|
||||||
: "NotoKufiArabic-Regular.ttf";
|
|
||||||
const candidates = [
|
const candidates = [
|
||||||
|
join(process.cwd(), "assets", file),
|
||||||
join(process.cwd(), "assets", "fonts", file),
|
join(process.cwd(), "assets", "fonts", file),
|
||||||
join(process.cwd(), "dist", "fonts", file),
|
join(process.cwd(), "dist", "assets", file),
|
||||||
join(process.cwd(), "dist", "assets", "fonts", file),
|
join(process.cwd(), "dist", "assets", "fonts", file),
|
||||||
join("/usr/share/fonts/truetype/noto", file),
|
|
||||||
];
|
];
|
||||||
for (const path of candidates) {
|
for (const path of candidates) {
|
||||||
if (existsSync(path)) return path;
|
if (existsSync(path)) return path;
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Persian PDF font not found (${file}). Place it under assets/fonts/ or install noto fonts on the host.`,
|
`Persian PDF font not found (${file}). Place it under assets/ or assets/fonts/.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +44,16 @@ export type PersianPdfDocument = InstanceType<typeof PDFDocument> & {
|
|||||||
addBlank: (lines?: number) => void;
|
addBlank: (lines?: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Ensure at least `neededPts` of vertical space remain; add a page if not. */
|
||||||
|
function ensureSpace(
|
||||||
|
doc: InstanceType<typeof PDFDocument>,
|
||||||
|
neededPts: number,
|
||||||
|
): void {
|
||||||
|
if (doc.y + neededPts > doc.page.maxY()) {
|
||||||
|
doc.addPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function drawRtlLine(
|
function drawRtlLine(
|
||||||
doc: InstanceType<typeof PDFDocument>,
|
doc: InstanceType<typeof PDFDocument>,
|
||||||
text: string,
|
text: string,
|
||||||
@@ -69,6 +77,9 @@ function drawKeyValueRow(
|
|||||||
label: string,
|
label: string,
|
||||||
value: string,
|
value: string,
|
||||||
): void {
|
): void {
|
||||||
|
// Reserve one row height (font 10pt ≈ 14 pts with leading) before drawing.
|
||||||
|
ensureSpace(doc, 16);
|
||||||
|
|
||||||
const y = doc.y;
|
const y = doc.y;
|
||||||
const { label: faLabel, value: faValue } = pdfKitRtlKeyValue(label, value);
|
const { label: faLabel, value: faValue } = pdfKitRtlKeyValue(label, value);
|
||||||
|
|
||||||
@@ -118,6 +129,9 @@ export function createPersianPdfDocument(): PersianPdfDocument {
|
|||||||
};
|
};
|
||||||
|
|
||||||
doc.addSection = (text: string) => {
|
doc.addSection = (text: string) => {
|
||||||
|
// Reserve space for the gap + section heading + at least one data row below it,
|
||||||
|
// so the heading is never stranded alone at the bottom of a page.
|
||||||
|
ensureSpace(doc, 60);
|
||||||
doc.moveDown(0.5);
|
doc.moveDown(0.5);
|
||||||
drawRtlLine(doc, text, 13, true);
|
drawRtlLine(doc, text, 13, true);
|
||||||
doc.font("FaRegular").fontSize(10);
|
doc.font("FaRegular").fontSize(10);
|
||||||
|
|||||||
@@ -8,18 +8,31 @@ export function normalizePersianPdfText(text: string): string {
|
|||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdfkit renders glyphs strictly left-to-right.
|
||||||
|
* fontkit already reshapes each word's glyphs into visual (LTR) order,
|
||||||
|
* but it does NOT reorder words — so a multi-word RTL string like
|
||||||
|
* "نام صاحب خودرو" has its words placed LTR on the page and reads
|
||||||
|
* backwards. Reversing the word sequence here makes pdfkit emit the
|
||||||
|
* words in the correct visual order for a right-to-left PDF reader.
|
||||||
|
*/
|
||||||
|
function reverseRtlWords(text: string): string {
|
||||||
|
if (!/[\u0600-\u06FF]/.test(text)) return text;
|
||||||
|
return text.split(" ").reverse().join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
export function pdfKitRtlKeyValue(
|
export function pdfKitRtlKeyValue(
|
||||||
label: string,
|
label: string,
|
||||||
value: string,
|
value: string,
|
||||||
): { label: string; value: string } {
|
): { label: string; value: string } {
|
||||||
return {
|
return {
|
||||||
label: normalizePersianPdfText(label),
|
label: reverseRtlWords(normalizePersianPdfText(label)),
|
||||||
value: normalizePersianPdfText(value),
|
value: reverseRtlWords(normalizePersianPdfText(value)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pdfKitRtlParagraph(text: string): string {
|
export function pdfKitRtlParagraph(text: string): string {
|
||||||
return normalizePersianPdfText(text);
|
return reverseRtlWords(normalizePersianPdfText(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMostlyAscii(text: string): boolean {
|
export function isMostlyAscii(text: string): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user