fix(ancpi): parse CF numbers and solutii separately, zip by position
The nested JSON in ePay HTML breaks [^}]* regex. New approach: find all CF.stringValues independently, find all solutii independently, then zip them by position (they appear in same order in HTML). This correctly maps CF number → document for batch orders. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -552,20 +552,28 @@ export class EpayClient {
|
||||
.replace(/ț/g, "ț")
|
||||
.replace(/ș/g, "ș");
|
||||
|
||||
// Parse metadateCereri blocks to match CF → solutii (document)
|
||||
// Each metadateCerere has: metadate.CF.stringValues[0] + solutii[{idDocument,...}]
|
||||
// Pattern: find each block with both CF and solutii
|
||||
const metadataPattern =
|
||||
/"metadate"\s*:\s*\{[^}]*"CF"\s*:\s*\{[^}]*"stringValues"\s*:\s*\["(\d+)"\][^]*?"solutii"\s*:\s*\[(\{[^[\]]*\})\]/g;
|
||||
// Strategy: find CF numbers and solutii separately, then match by position.
|
||||
// In the HTML, each metadateCereri block has both CF.stringValues and solutii
|
||||
// in the same order. We find them independently and zip them.
|
||||
|
||||
let metaMatch;
|
||||
while ((metaMatch = metadataPattern.exec(decoded)) !== null) {
|
||||
const cfNumber = metaMatch[1] ?? "";
|
||||
// 1. Find all CF numbers: "CF":{"name":"CF",...,"stringValues":["345295"]}
|
||||
const cfPattern = /"CF"\s*:\s*\{[^}]*"stringValues"\s*:\s*\["(\d+)"\]/g;
|
||||
const cfNumbers: string[] = [];
|
||||
let cfMatch;
|
||||
while ((cfMatch = cfPattern.exec(decoded)) !== null) {
|
||||
cfNumbers.push(cfMatch[1] ?? "");
|
||||
}
|
||||
|
||||
// 2. Find all solutii blocks (CF extracts only, idTipDocument=null)
|
||||
const solutiiPattern = /"solutii"\s*:\s*\[(\{[^[\]]*\})\]/g;
|
||||
const allSolutii: EpaySolutionDoc[] = [];
|
||||
let solutiiMatch;
|
||||
while ((solutiiMatch = solutiiPattern.exec(decoded)) !== null) {
|
||||
try {
|
||||
const solutii = JSON.parse(`[${metaMatch[2]}]`);
|
||||
for (const s of solutii) {
|
||||
const arr = JSON.parse(`[${solutiiMatch[1]}]`);
|
||||
for (const s of arr) {
|
||||
if (s?.idDocument && s?.idTipDocument === null) {
|
||||
const doc: EpaySolutionDoc = {
|
||||
allSolutii.push({
|
||||
idDocument: s.idDocument,
|
||||
idTipDocument: null,
|
||||
nume: s.nume ?? "",
|
||||
@@ -578,43 +586,26 @@ export class EpayClient {
|
||||
valabilNelimitat: s.valabilNelimitat ?? true,
|
||||
zileValabilitateDownload: s.zileValabilitateDownload ?? -1,
|
||||
transactionId: s.transactionId ?? 0,
|
||||
};
|
||||
documents.push(doc);
|
||||
if (cfNumber) documentsByCadastral.set(cfNumber, doc);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch { /* parse failed */ }
|
||||
}
|
||||
|
||||
// Fallback: simpler solutii pattern (without CF matching)
|
||||
if (documents.length === 0) {
|
||||
const solutiiPattern = /"solutii"\s*:\s*\[(\{[^[\]]*\})\]/g;
|
||||
let solutiiMatch;
|
||||
while ((solutiiMatch = solutiiPattern.exec(decoded)) !== null) {
|
||||
try {
|
||||
const arr = JSON.parse(`[${solutiiMatch[1]}]`);
|
||||
for (const s of arr) {
|
||||
if (s?.idDocument && s?.idTipDocument === null) {
|
||||
documents.push({
|
||||
idDocument: s.idDocument,
|
||||
idTipDocument: null,
|
||||
nume: s.nume ?? "",
|
||||
numar: s.numar ?? null,
|
||||
serie: s.serie ?? null,
|
||||
dataDocument: s.dataDocument ?? "",
|
||||
contentType: s.contentType ?? "application/pdf",
|
||||
linkDownload: s.linkDownload ?? "",
|
||||
downloadValabil: s.downloadValabil ?? true,
|
||||
valabilNelimitat: s.valabilNelimitat ?? true,
|
||||
zileValabilitateDownload: s.zileValabilitateDownload ?? -1,
|
||||
transactionId: s.transactionId ?? 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch { /* parse failed */ }
|
||||
// 3. Zip CF numbers with solutii — they appear in the same order
|
||||
documents.push(...allSolutii);
|
||||
for (let i = 0; i < Math.min(cfNumbers.length, allSolutii.length); i++) {
|
||||
const cf = cfNumbers[i];
|
||||
const doc = allSolutii[i];
|
||||
if (cf && doc) {
|
||||
documentsByCadastral.set(cf, doc);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[epay] Order ${orderId}: CFs=[${cfNumbers.join(",")}], docs=${allSolutii.length}, matched=${documentsByCadastral.size}`,
|
||||
);
|
||||
|
||||
if (documents.length === 0 && status === "Finalizata") {
|
||||
console.warn(`[epay] Order ${orderId}: Finalizata but no documents found`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user