@finsys/core 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -504,6 +504,11 @@ interface ExtractionStatusResult {
504
504
  /**
505
505
  * Determines per-document extraction status from IHS record data.
506
506
  *
507
+ * For multi-file document types (bank statements, financial statements, EPF,
508
+ * payslips) the result contains one entry per uploaded file, indexed in the
509
+ * same order as the files appear in the IHS record's aggregate array.
510
+ * For single-file types (SSM, Form 9, IC) there is one entry.
511
+ *
507
512
  * @param ihsRecord - The IHS application record (any shape satisfying Record<string, unknown>)
508
513
  * @param jobRecords - Extraction job records for this IHS. Pass the array (even if empty)
509
514
  * when job records were fetched. Omit or pass undefined when job records are unavailable;
package/dist/index.d.ts CHANGED
@@ -504,6 +504,11 @@ interface ExtractionStatusResult {
504
504
  /**
505
505
  * Determines per-document extraction status from IHS record data.
506
506
  *
507
+ * For multi-file document types (bank statements, financial statements, EPF,
508
+ * payslips) the result contains one entry per uploaded file, indexed in the
509
+ * same order as the files appear in the IHS record's aggregate array.
510
+ * For single-file types (SSM, Form 9, IC) there is one entry.
511
+ *
507
512
  * @param ihsRecord - The IHS application record (any shape satisfying Record<string, unknown>)
508
513
  * @param jobRecords - Extraction job records for this IHS. Pass the array (even if empty)
509
514
  * when job records were fetched. Omit or pass undefined when job records are unavailable;
package/dist/index.js CHANGED
@@ -9495,9 +9495,12 @@ function processIhsDetails(ihsData) {
9495
9495
  const specs = getBaseFieldSpecs();
9496
9496
  const fileColumnSet = /* @__PURE__ */ new Set();
9497
9497
  for (const field of specs) {
9498
- if (field.type === "file" && field.ihs_column_names) {
9499
- for (const col of field.ihs_column_names) {
9500
- fileColumnSet.add(col);
9498
+ if (field.type === "file") {
9499
+ if (field.name) fileColumnSet.add(field.name);
9500
+ if (field.ihs_column_names) {
9501
+ for (const col of field.ihs_column_names) {
9502
+ fileColumnSet.add(col);
9503
+ }
9501
9504
  }
9502
9505
  }
9503
9506
  }
@@ -9599,59 +9602,45 @@ function isPopulated(value) {
9599
9602
  if (value === "Not Specified") return false;
9600
9603
  return true;
9601
9604
  }
9602
- function hasUploadedFile(fields, ihsRecord) {
9603
- return fields.some((field) => {
9604
- if (!field.name) return false;
9605
- return isPopulated(ihsRecord[field.name]);
9606
- });
9607
- }
9608
- function getExtractionColumns(fields) {
9609
- const columns = [];
9610
- for (const field of fields) {
9611
- if (field.ihs_column_names) {
9612
- columns.push(...field.ihs_column_names);
9605
+ function countUploadedFiles(ihsRecord, aggregateKey) {
9606
+ const raw = ihsRecord[aggregateKey];
9607
+ if (!raw) return 0;
9608
+ if (typeof raw === "string") {
9609
+ try {
9610
+ const parsed = JSON.parse(raw);
9611
+ if (Array.isArray(parsed)) return parsed.length;
9612
+ } catch {
9613
+ return 1;
9613
9614
  }
9614
9615
  }
9615
- return columns;
9616
+ if (Array.isArray(raw)) return raw.length;
9617
+ return 1;
9616
9618
  }
9617
9619
  function getPopulatedColumns(columns, ihsRecord) {
9618
9620
  return columns.filter((col) => isPopulated(ihsRecord[col]));
9619
9621
  }
9620
- function resolveExtractionStatus(ihsRecord, jobRecords) {
9621
- const documents = [];
9622
- for (const fileType of Object.values(ExtractionFileType)) {
9623
- const groupName = FILE_TYPE_TO_GROUP[fileType];
9624
- const fields = _grouped[groupName] ?? [];
9625
- const displayName = _groupDisplayNames[groupName] ?? fileType;
9626
- const uploaded = fields.length > 0 && hasUploadedFile(fields, ihsRecord);
9627
- const allColumns = getExtractionColumns(fields);
9628
- const populated = getPopulatedColumns(allColumns, ihsRecord);
9629
- const hasExtractedData = populated.length > 0;
9630
- let status;
9631
- let errorMessage;
9632
- if (!uploaded) {
9633
- status = "not_uploaded" /* NotUploaded */;
9634
- } else if (jobRecords) {
9635
- const job = jobRecords.find((j) => j.fileType === fileType);
9636
- if (job) {
9637
- if (job.status === "queued" /* Queued */) {
9638
- status = "queued" /* Queued */;
9639
- } else if (job.status === "processing" /* Processing */) {
9640
- status = "processing" /* Processing */;
9641
- } else if (job.status === "failed" /* Failed */) {
9642
- if (hasExtractedData) {
9643
- status = "extracted" /* Extracted */;
9644
- errorMessage = job.errorMessage;
9645
- } else {
9646
- status = "failed" /* Failed */;
9647
- errorMessage = job.errorMessage;
9648
- }
9649
- } else if (job.status === "succeeded" /* Succeeded */ || hasExtractedData) {
9622
+ function resolveDocStatus(columns, ihsRecord, uploaded, jobRecord, hasJobRecords) {
9623
+ const populated = getPopulatedColumns(columns, ihsRecord);
9624
+ const hasExtractedData = populated.length > 0;
9625
+ let status;
9626
+ let errorMessage;
9627
+ if (!uploaded) {
9628
+ status = "not_uploaded" /* NotUploaded */;
9629
+ } else if (hasJobRecords) {
9630
+ if (jobRecord) {
9631
+ if (jobRecord.status === "queued" /* Queued */) {
9632
+ status = "queued" /* Queued */;
9633
+ } else if (jobRecord.status === "processing" /* Processing */) {
9634
+ status = "processing" /* Processing */;
9635
+ } else if (jobRecord.status === "failed" /* Failed */) {
9636
+ if (hasExtractedData) {
9650
9637
  status = "extracted" /* Extracted */;
9638
+ errorMessage = jobRecord.errorMessage;
9651
9639
  } else {
9652
- status = "uploaded" /* Uploaded */;
9640
+ status = "failed" /* Failed */;
9641
+ errorMessage = jobRecord.errorMessage;
9653
9642
  }
9654
- } else if (hasExtractedData) {
9643
+ } else if (jobRecord.status === "succeeded" /* Succeeded */ || hasExtractedData) {
9655
9644
  status = "extracted" /* Extracted */;
9656
9645
  } else {
9657
9646
  status = "uploaded" /* Uploaded */;
@@ -9659,16 +9648,68 @@ function resolveExtractionStatus(ihsRecord, jobRecords) {
9659
9648
  } else if (hasExtractedData) {
9660
9649
  status = "extracted" /* Extracted */;
9661
9650
  } else {
9662
- status = "unknown" /* Unknown */;
9651
+ status = "uploaded" /* Uploaded */;
9652
+ }
9653
+ } else if (hasExtractedData) {
9654
+ status = "extracted" /* Extracted */;
9655
+ } else {
9656
+ status = "unknown" /* Unknown */;
9657
+ }
9658
+ return { status, errorMessage };
9659
+ }
9660
+ function resolveExtractionStatus(ihsRecord, jobRecords) {
9661
+ const documents = [];
9662
+ const hasJobRecords = jobRecords !== void 0;
9663
+ for (const fileType of Object.values(ExtractionFileType)) {
9664
+ const groupName = FILE_TYPE_TO_GROUP[fileType];
9665
+ const fields = _grouped[groupName] ?? [];
9666
+ const displayName = _groupDisplayNames[groupName] ?? fileType;
9667
+ const uploadedCount = countUploadedFiles(ihsRecord, fileType);
9668
+ const isUploaded = uploadedCount > 0 || fields.some((f) => f.name && isPopulated(ihsRecord[f.name]));
9669
+ const matchingJobs = jobRecords?.filter((j) => j.fileType === fileType) ?? [];
9670
+ if (fields.length <= 1) {
9671
+ const field = fields[0];
9672
+ const columns = field?.ihs_column_names ?? [];
9673
+ const populated = getPopulatedColumns(columns, ihsRecord);
9674
+ const { status, errorMessage } = resolveDocStatus(
9675
+ columns,
9676
+ ihsRecord,
9677
+ isUploaded,
9678
+ matchingJobs[0],
9679
+ hasJobRecords
9680
+ );
9681
+ documents.push({
9682
+ fileType,
9683
+ status,
9684
+ displayName,
9685
+ populatedColumns: populated,
9686
+ totalColumns: columns.length,
9687
+ errorMessage
9688
+ });
9689
+ } else {
9690
+ const count = Math.max(uploadedCount, 1);
9691
+ for (let idx = 0; idx < count; idx++) {
9692
+ const field = fields[idx];
9693
+ const columns = field?.ihs_column_names ?? [];
9694
+ const populated = getPopulatedColumns(columns, ihsRecord);
9695
+ const fileUploaded = idx < uploadedCount;
9696
+ const { status, errorMessage } = resolveDocStatus(
9697
+ columns,
9698
+ ihsRecord,
9699
+ fileUploaded,
9700
+ matchingJobs[idx],
9701
+ hasJobRecords
9702
+ );
9703
+ documents.push({
9704
+ fileType,
9705
+ status,
9706
+ displayName,
9707
+ populatedColumns: populated,
9708
+ totalColumns: columns.length,
9709
+ errorMessage
9710
+ });
9711
+ }
9663
9712
  }
9664
- documents.push({
9665
- fileType,
9666
- status,
9667
- displayName,
9668
- populatedColumns: populated,
9669
- totalColumns: allColumns.length,
9670
- errorMessage
9671
- });
9672
9713
  }
9673
9714
  const summary = documents.reduce(
9674
9715
  (acc, d) => {