@powerhousedao/contributor-billing 0.0.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/LICENSE +661 -0
- package/README.md +22 -0
- package/dist/document-models/index.d.ts +2 -0
- package/dist/document-models/index.d.ts.map +1 -0
- package/dist/document-models/index.js +1 -0
- package/dist/document-models/invoice/gen/actions.d.ts +8 -0
- package/dist/document-models/invoice/gen/actions.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/actions.js +3 -0
- package/dist/document-models/invoice/gen/creators.d.ts +4 -0
- package/dist/document-models/invoice/gen/creators.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/creators.js +3 -0
- package/dist/document-models/invoice/gen/document-model.d.ts +3 -0
- package/dist/document-models/invoice/gen/document-model.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/document-model.js +227 -0
- package/dist/document-models/invoice/gen/general/actions.d.ts +10 -0
- package/dist/document-models/invoice/gen/general/actions.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/general/actions.js +1 -0
- package/dist/document-models/invoice/gen/general/creators.d.ts +9 -0
- package/dist/document-models/invoice/gen/general/creators.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/general/creators.js +8 -0
- package/dist/document-models/invoice/gen/general/error.d.ts +2 -0
- package/dist/document-models/invoice/gen/general/error.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/general/error.js +1 -0
- package/dist/document-models/invoice/gen/general/object.d.ts +12 -0
- package/dist/document-models/invoice/gen/general/object.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/general/object.js +22 -0
- package/dist/document-models/invoice/gen/general/operations.d.ts +12 -0
- package/dist/document-models/invoice/gen/general/operations.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/general/operations.js +1 -0
- package/dist/document-models/invoice/gen/index.d.ts +6 -0
- package/dist/document-models/invoice/gen/index.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/index.js +5 -0
- package/dist/document-models/invoice/gen/items/actions.d.ts +8 -0
- package/dist/document-models/invoice/gen/items/actions.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/items/actions.js +1 -0
- package/dist/document-models/invoice/gen/items/creators.d.ts +7 -0
- package/dist/document-models/invoice/gen/items/creators.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/items/creators.js +6 -0
- package/dist/document-models/invoice/gen/items/error.d.ts +2 -0
- package/dist/document-models/invoice/gen/items/error.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/items/error.js +1 -0
- package/dist/document-models/invoice/gen/items/object.d.ts +10 -0
- package/dist/document-models/invoice/gen/items/object.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/items/object.js +16 -0
- package/dist/document-models/invoice/gen/items/operations.d.ts +10 -0
- package/dist/document-models/invoice/gen/items/operations.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/items/operations.js +1 -0
- package/dist/document-models/invoice/gen/object.d.ts +20 -0
- package/dist/document-models/invoice/gen/object.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/object.js +29 -0
- package/dist/document-models/invoice/gen/parties/actions.d.ts +10 -0
- package/dist/document-models/invoice/gen/parties/actions.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/parties/actions.js +1 -0
- package/dist/document-models/invoice/gen/parties/creators.d.ts +9 -0
- package/dist/document-models/invoice/gen/parties/creators.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/parties/creators.js +8 -0
- package/dist/document-models/invoice/gen/parties/error.d.ts +2 -0
- package/dist/document-models/invoice/gen/parties/error.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/parties/error.js +1 -0
- package/dist/document-models/invoice/gen/parties/object.d.ts +12 -0
- package/dist/document-models/invoice/gen/parties/object.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/parties/object.js +22 -0
- package/dist/document-models/invoice/gen/parties/operations.d.ts +12 -0
- package/dist/document-models/invoice/gen/parties/operations.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/parties/operations.js +1 -0
- package/dist/document-models/invoice/gen/reducer.d.ts +3 -0
- package/dist/document-models/invoice/gen/reducer.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/reducer.js +79 -0
- package/dist/document-models/invoice/gen/schema/index.d.ts +3 -0
- package/dist/document-models/invoice/gen/schema/index.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/schema/index.js +2 -0
- package/dist/document-models/invoice/gen/schema/types.d.ts +390 -0
- package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/schema/types.js +1 -0
- package/dist/document-models/invoice/gen/schema/zod.d.ts +56 -0
- package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/schema/zod.js +362 -0
- package/dist/document-models/invoice/gen/types.d.ts +10 -0
- package/dist/document-models/invoice/gen/types.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/types.js +1 -0
- package/dist/document-models/invoice/gen/utils.d.ts +7 -0
- package/dist/document-models/invoice/gen/utils.d.ts.map +1 -0
- package/dist/document-models/invoice/gen/utils.js +166 -0
- package/dist/document-models/invoice/index.d.ts +41 -0
- package/dist/document-models/invoice/index.d.ts.map +1 -0
- package/dist/document-models/invoice/index.js +21 -0
- package/dist/document-models/invoice/src/reducers/general.d.ts +8 -0
- package/dist/document-models/invoice/src/reducers/general.d.ts.map +1 -0
- package/dist/document-models/invoice/src/reducers/general.js +79 -0
- package/dist/document-models/invoice/src/reducers/items.d.ts +8 -0
- package/dist/document-models/invoice/src/reducers/items.d.ts.map +1 -0
- package/dist/document-models/invoice/src/reducers/items.js +108 -0
- package/dist/document-models/invoice/src/reducers/parties.d.ts +8 -0
- package/dist/document-models/invoice/src/reducers/parties.d.ts.map +1 -0
- package/dist/document-models/invoice/src/reducers/parties.js +266 -0
- package/dist/document-models/invoice/src/tests/document-model.test.d.ts +6 -0
- package/dist/document-models/invoice/src/tests/document-model.test.d.ts.map +1 -0
- package/dist/document-models/invoice/src/tests/document-model.test.js +17 -0
- package/dist/document-models/invoice/src/tests/general.test.d.ts +6 -0
- package/dist/document-models/invoice/src/tests/general.test.d.ts.map +1 -0
- package/dist/document-models/invoice/src/tests/general.test.js +75 -0
- package/dist/document-models/invoice/src/tests/items.test.d.ts +6 -0
- package/dist/document-models/invoice/src/tests/items.test.d.ts.map +1 -0
- package/dist/document-models/invoice/src/tests/items.test.js +45 -0
- package/dist/document-models/invoice/src/tests/parties.test.d.ts +6 -0
- package/dist/document-models/invoice/src/tests/parties.test.d.ts.map +1 -0
- package/dist/document-models/invoice/src/tests/parties.test.js +75 -0
- package/dist/document-models/invoice/src/utils.d.ts +2 -0
- package/dist/document-models/invoice/src/utils.d.ts.map +1 -0
- package/dist/document-models/invoice/src/utils.js +1 -0
- package/dist/editors/contributor-billing/components/CreateDocument.d.ts +8 -0
- package/dist/editors/contributor-billing/components/CreateDocument.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/CreateDocument.js +14 -0
- package/dist/editors/contributor-billing/components/DocumentDispatch.d.ts +12 -0
- package/dist/editors/contributor-billing/components/DocumentDispatch.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/DocumentDispatch.js +20 -0
- package/dist/editors/contributor-billing/components/DriveExplorer.d.ts +17 -0
- package/dist/editors/contributor-billing/components/DriveExplorer.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/DriveExplorer.js +112 -0
- package/dist/editors/contributor-billing/components/EditorContainer.d.ts +14 -0
- package/dist/editors/contributor-billing/components/EditorContainer.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/EditorContainer.js +28 -0
- package/dist/editors/contributor-billing/components/FileItemsGrid.d.ts +12 -0
- package/dist/editors/contributor-billing/components/FileItemsGrid.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/FileItemsGrid.js +7 -0
- package/dist/editors/contributor-billing/components/FolderItemsGrid.d.ts +17 -0
- package/dist/editors/contributor-billing/components/FolderItemsGrid.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/FolderItemsGrid.js +14 -0
- package/dist/editors/contributor-billing/components/FolderTree.d.ts +9 -0
- package/dist/editors/contributor-billing/components/FolderTree.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/FolderTree.js +31 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts +16 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/HeaderControls.js +16 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts +21 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.js +45 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableRow.d.ts +12 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableRow.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableRow.js +12 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.d.ts +7 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTableSection.js +7 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/RowActionMenu.d.ts +8 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/RowActionMenu.d.ts.map +1 -0
- package/dist/editors/contributor-billing/components/InvoiceTable/RowActionMenu.js +2 -0
- package/dist/editors/contributor-billing/editor.d.ts +6 -0
- package/dist/editors/contributor-billing/editor.d.ts.map +1 -0
- package/dist/editors/contributor-billing/editor.js +48 -0
- package/dist/editors/contributor-billing/hooks/useDispatchMap.d.ts +9 -0
- package/dist/editors/contributor-billing/hooks/useDispatchMap.d.ts.map +1 -0
- package/dist/editors/contributor-billing/hooks/useDispatchMap.js +21 -0
- package/dist/editors/contributor-billing/hooks/useDrop.d.ts +22 -0
- package/dist/editors/contributor-billing/hooks/useDrop.d.ts.map +1 -0
- package/dist/editors/contributor-billing/hooks/useDrop.js +57 -0
- package/dist/editors/contributor-billing/hooks/useSelectedFolderChildren.d.ts +8 -0
- package/dist/editors/contributor-billing/hooks/useSelectedFolderChildren.d.ts.map +1 -0
- package/dist/editors/contributor-billing/hooks/useSelectedFolderChildren.js +19 -0
- package/dist/editors/contributor-billing/hooks/useTransformedNodes.d.ts +4 -0
- package/dist/editors/contributor-billing/hooks/useTransformedNodes.d.ts.map +1 -0
- package/dist/editors/contributor-billing/hooks/useTransformedNodes.js +32 -0
- package/dist/editors/contributor-billing/index.d.ts +5 -0
- package/dist/editors/contributor-billing/index.d.ts.map +1 -0
- package/dist/editors/contributor-billing/index.js +12 -0
- package/dist/editors/index.d.ts +3 -0
- package/dist/editors/index.d.ts.map +1 -0
- package/dist/editors/index.js +2 -0
- package/dist/editors/invoice/InvoicePDF.d.ts +8 -0
- package/dist/editors/invoice/InvoicePDF.d.ts.map +1 -0
- package/dist/editors/invoice/InvoicePDF.js +359 -0
- package/dist/editors/invoice/assets/custom.d.ts +4 -0
- package/dist/editors/invoice/assets/powerhouseLogo.png +0 -0
- package/dist/editors/invoice/components/countryForm.d.ts +12 -0
- package/dist/editors/invoice/components/countryForm.d.ts.map +1 -0
- package/dist/editors/invoice/components/countryForm.js +28 -0
- package/dist/editors/invoice/components/currencyForm.d.ts +13 -0
- package/dist/editors/invoice/components/currencyForm.d.ts.map +1 -0
- package/dist/editors/invoice/components/currencyForm.js +26 -0
- package/dist/editors/invoice/components/datePicker.d.ts +11 -0
- package/dist/editors/invoice/components/datePicker.d.ts.map +1 -0
- package/dist/editors/invoice/components/datePicker.js +8 -0
- package/dist/editors/invoice/components/inputField.d.ts +14 -0
- package/dist/editors/invoice/components/inputField.d.ts.map +1 -0
- package/dist/editors/invoice/components/inputField.js +25 -0
- package/dist/editors/invoice/components/numberForm.d.ts +11 -0
- package/dist/editors/invoice/components/numberForm.d.ts.map +1 -0
- package/dist/editors/invoice/components/numberForm.js +7 -0
- package/dist/editors/invoice/components/selectField.d.ts +8 -0
- package/dist/editors/invoice/components/selectField.d.ts.map +1 -0
- package/dist/editors/invoice/components/selectField.js +323 -0
- package/dist/editors/invoice/editor.d.ts +5 -0
- package/dist/editors/invoice/editor.d.ts.map +1 -0
- package/dist/editors/invoice/editor.js +377 -0
- package/dist/editors/invoice/exportUBL.d.ts +85 -0
- package/dist/editors/invoice/exportUBL.d.ts.map +1 -0
- package/dist/editors/invoice/exportUBL.js +382 -0
- package/dist/editors/invoice/index.d.ts +5 -0
- package/dist/editors/invoice/index.d.ts.map +1 -0
- package/dist/editors/invoice/index.js +12 -0
- package/dist/editors/invoice/ingestPDF.d.ts +12 -0
- package/dist/editors/invoice/ingestPDF.d.ts.map +1 -0
- package/dist/editors/invoice/ingestPDF.js +193 -0
- package/dist/editors/invoice/ingestUBL.d.ts +21 -0
- package/dist/editors/invoice/ingestUBL.d.ts.map +1 -0
- package/dist/editors/invoice/ingestUBL.js +169 -0
- package/dist/editors/invoice/invoiceToGnosis.d.ts +7 -0
- package/dist/editors/invoice/invoiceToGnosis.d.ts.map +1 -0
- package/dist/editors/invoice/invoiceToGnosis.js +139 -0
- package/dist/editors/invoice/legalEntity/bankSection.d.ts +14 -0
- package/dist/editors/invoice/legalEntity/bankSection.d.ts.map +1 -0
- package/dist/editors/invoice/legalEntity/bankSection.js +156 -0
- package/dist/editors/invoice/legalEntity/common.d.ts +6 -0
- package/dist/editors/invoice/legalEntity/common.d.ts.map +1 -0
- package/dist/editors/invoice/legalEntity/common.js +6 -0
- package/dist/editors/invoice/legalEntity/legalEntity.d.ts +40 -0
- package/dist/editors/invoice/legalEntity/legalEntity.d.ts.map +1 -0
- package/dist/editors/invoice/legalEntity/legalEntity.js +63 -0
- package/dist/editors/invoice/legalEntity/walletSection.d.ts +13 -0
- package/dist/editors/invoice/legalEntity/walletSection.d.ts.map +1 -0
- package/dist/editors/invoice/legalEntity/walletSection.js +55 -0
- package/dist/editors/invoice/lineItems.d.ts +23 -0
- package/dist/editors/invoice/lineItems.d.ts.map +1 -0
- package/dist/editors/invoice/lineItems.js +157 -0
- package/dist/editors/invoice/requestFinance.d.ts +7 -0
- package/dist/editors/invoice/requestFinance.d.ts.map +1 -0
- package/dist/editors/invoice/requestFinance.js +155 -0
- package/dist/editors/invoice/uploadPdfChunked.d.ts +10 -0
- package/dist/editors/invoice/uploadPdfChunked.d.ts.map +1 -0
- package/dist/editors/invoice/uploadPdfChunked.js +79 -0
- package/dist/editors/invoice/utils/utils.d.ts +2 -0
- package/dist/editors/invoice/utils/utils.d.ts.map +1 -0
- package/dist/editors/invoice/utils/utils.js +54 -0
- package/dist/editors/invoice/validation/validationManager.d.ts +28 -0
- package/dist/editors/invoice/validation/validationManager.d.ts.map +1 -0
- package/dist/editors/invoice/validation/validationManager.js +65 -0
- package/dist/editors/invoice/validation/validationRules.d.ts +14 -0
- package/dist/editors/invoice/validation/validationRules.d.ts.map +1 -0
- package/dist/editors/invoice/validation/validationRules.js +334 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/powerhouse.manifest.json +31 -0
- package/dist/processors/index.d.ts +2 -0
- package/dist/processors/index.d.ts.map +1 -0
- package/dist/processors/index.js +1 -0
- package/dist/scripts/invoice/exampleBatchTxn.d.ts +2 -0
- package/dist/scripts/invoice/exampleBatchTxn.d.ts.map +1 -0
- package/dist/scripts/invoice/exampleBatchTxn.js +44 -0
- package/dist/scripts/invoice/gnosisTransactionBuilder.d.ts +28 -0
- package/dist/scripts/invoice/gnosisTransactionBuilder.d.ts.map +1 -0
- package/dist/scripts/invoice/gnosisTransactionBuilder.js +74 -0
- package/dist/scripts/invoice/pdfToDocumentAi.d.ts +5 -0
- package/dist/scripts/invoice/pdfToDocumentAi.d.ts.map +1 -0
- package/dist/scripts/invoice/pdfToDocumentAi.js +659 -0
- package/dist/scripts/invoice/requestFinance.d.ts +2 -0
- package/dist/scripts/invoice/requestFinance.d.ts.map +1 -0
- package/dist/scripts/invoice/requestFinance.js +38 -0
- package/dist/style.css +6463 -0
- package/dist/subgraphs/index.d.ts +2 -0
- package/dist/subgraphs/index.d.ts.map +1 -0
- package/dist/subgraphs/index.js +1 -0
- package/dist/subgraphs/invoice/customResolvers.d.ts +50 -0
- package/dist/subgraphs/invoice/customResolvers.d.ts.map +1 -0
- package/dist/subgraphs/invoice/customResolvers.js +327 -0
- package/dist/subgraphs/invoice/index.d.ts +10 -0
- package/dist/subgraphs/invoice/index.d.ts.map +1 -0
- package/dist/subgraphs/invoice/index.js +30 -0
- package/dist/subgraphs/invoice/resolvers.d.ts +3 -0
- package/dist/subgraphs/invoice/resolvers.d.ts.map +1 -0
- package/dist/subgraphs/invoice/resolvers.js +184 -0
- package/dist/subgraphs/invoice/schema.d.ts +3 -0
- package/dist/subgraphs/invoice/schema.d.ts.map +1 -0
- package/dist/subgraphs/invoice/schema.js +460 -0
- package/dist/tailwind.config.d.ts +13 -0
- package/dist/tailwind.config.d.ts.map +1 -0
- package/dist/tailwind.config.js +15 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +8 -0
- package/editors/invoice/assets/custom.d.ts +4 -0
- package/editors/invoice/assets/powerhouseLogo.png +0 -0
- package/package.json +117 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import { DocumentProcessorServiceClient } from '@google-cloud/documentai';
|
|
2
|
+
import { GoogleAuth } from 'google-auth-library';
|
|
3
|
+
import crypto from 'crypto';
|
|
4
|
+
export async function uploadPdfAndGetJson(inputDoc) {
|
|
5
|
+
try {
|
|
6
|
+
console.log("Starting PDF upload and processing"); // Log when processing starts
|
|
7
|
+
const projectId = process.env.GOOGLE_CLOUD_PROJECT_ID;
|
|
8
|
+
const location = process.env.GOOGLE_CLOUD_LOCATION;
|
|
9
|
+
const processorId = process.env.GOOGLE_CLOUD_PROCESSOR_ID;
|
|
10
|
+
console.log("Initializing Document AI client..."); // New log
|
|
11
|
+
const auth = new GoogleAuth({
|
|
12
|
+
keyFile: process.env.GOOGLE_CLOUD_KEY_FILE,
|
|
13
|
+
scopes: 'https://www.googleapis.com/auth/cloud-platform',
|
|
14
|
+
});
|
|
15
|
+
const client = new DocumentProcessorServiceClient({ auth });
|
|
16
|
+
console.log("Preparing document request..."); // New log
|
|
17
|
+
const document = { content: inputDoc, mimeType: 'application/pdf' };
|
|
18
|
+
const request = {
|
|
19
|
+
name: `projects/${projectId}/locations/${location}/processors/${processorId}`,
|
|
20
|
+
rawDocument: document,
|
|
21
|
+
};
|
|
22
|
+
console.log("Sending request to Document AI..."); // New log
|
|
23
|
+
const [result] = await client.processDocument(request);
|
|
24
|
+
console.log("PDF processed successfully"); // Original log
|
|
25
|
+
// Extract useful sections from the JSON data using recursive function
|
|
26
|
+
const extractEntities = (entities) => {
|
|
27
|
+
return entities.flatMap(entity => {
|
|
28
|
+
const extracted = {
|
|
29
|
+
type: entity.type,
|
|
30
|
+
mentionText: entity.mentionText,
|
|
31
|
+
confidence: entity.confidence,
|
|
32
|
+
children: []
|
|
33
|
+
};
|
|
34
|
+
if (entity.properties && entity.properties.length > 0) {
|
|
35
|
+
extracted.children = extractEntities(entity.properties);
|
|
36
|
+
}
|
|
37
|
+
return extracted;
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const entities = extractEntities(result.document.entities);
|
|
41
|
+
// console.log("Entities:", JSON.stringify(entities, null, 2));
|
|
42
|
+
// Map the entities to invoice format
|
|
43
|
+
const invoiceData = mapDocumentAiToInvoice(entities);
|
|
44
|
+
// console.log("Mapped invoice data:", JSON.stringify(invoiceData, null, 2));
|
|
45
|
+
return { invoiceData };
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error("Error in uploadPdfAndGetJson:", error); // Add error logging
|
|
49
|
+
throw error; // Re-throw to handle in the API route
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseDate(dateStr) {
|
|
53
|
+
try {
|
|
54
|
+
if (!dateStr || typeof dateStr !== 'string') {
|
|
55
|
+
console.error(`Invalid date input: ${dateStr}`);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
// Remove any leading/trailing whitespace and convert to uppercase for consistency
|
|
59
|
+
dateStr = dateStr.trim().toUpperCase();
|
|
60
|
+
// Remove ordinal indicators (TH, ST, ND, RD)
|
|
61
|
+
dateStr = dateStr.replace(/(\d+)(ST|ND|RD|TH)/g, '$1');
|
|
62
|
+
let date = null;
|
|
63
|
+
// Handle YYYY-MM-DD format
|
|
64
|
+
if (dateStr.match(/^\d{4}-\d{1,2}-\d{1,2}$/)) {
|
|
65
|
+
const [year, month, day] = dateStr.split('-');
|
|
66
|
+
date = new Date(`${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`);
|
|
67
|
+
}
|
|
68
|
+
// Handle DD/MMM/YYYY format (e.g., "02/JAN/2025")
|
|
69
|
+
else if (dateStr.match(/^\d{1,2}\/[A-Z]{3}\/\d{4}$/)) {
|
|
70
|
+
const [day, month, year] = dateStr.split('/');
|
|
71
|
+
const monthMap = {
|
|
72
|
+
'JAN': '01', 'FEB': '02', 'MAR': '03', 'APR': '04',
|
|
73
|
+
'MAY': '05', 'JUN': '06', 'JUL': '07', 'AUG': '08',
|
|
74
|
+
'SEP': '09', 'OCT': '10', 'NOV': '11', 'DEC': '12'
|
|
75
|
+
};
|
|
76
|
+
date = new Date(`${year}-${monthMap[month]}-${day.padStart(2, '0')}`);
|
|
77
|
+
}
|
|
78
|
+
// Handle DD-MMM-YYYY format (e.g., "02-JAN-2025")
|
|
79
|
+
else if (dateStr.match(/^\d{1,2}-[A-Z]{3}-\d{4}$/)) {
|
|
80
|
+
const [day, month, year] = dateStr.split('-');
|
|
81
|
+
const monthMap = {
|
|
82
|
+
'JAN': '01', 'FEB': '02', 'MAR': '03', 'APR': '04',
|
|
83
|
+
'MAY': '05', 'JUN': '06', 'JUL': '07', 'AUG': '08',
|
|
84
|
+
'SEP': '09', 'OCT': '10', 'NOV': '11', 'DEC': '12'
|
|
85
|
+
};
|
|
86
|
+
date = new Date(`${year}-${monthMap[month]}-${day.padStart(2, '0')}`);
|
|
87
|
+
}
|
|
88
|
+
// Handle MM/DD/YYYY format
|
|
89
|
+
else if (dateStr.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
|
|
90
|
+
const [month, day, year] = dateStr.split('/');
|
|
91
|
+
date = new Date(`${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`);
|
|
92
|
+
}
|
|
93
|
+
// Handle DD.MM.YYYY format (European)
|
|
94
|
+
else if (dateStr.match(/^\d{1,2}\.\d{1,2}\.\d{4}$/)) {
|
|
95
|
+
const [day, month, year] = dateStr.split('.');
|
|
96
|
+
date = new Date(`${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`);
|
|
97
|
+
}
|
|
98
|
+
// Handle "MONTH DAY, YEAR" format (e.g., "MARCH 5, 2025")
|
|
99
|
+
else if (dateStr.match(/^[A-Z]+ \d{1,2},? \d{4}$/)) {
|
|
100
|
+
const monthMap = {
|
|
101
|
+
'JANUARY': '01', 'FEBRUARY': '02', 'MARCH': '03', 'APRIL': '04',
|
|
102
|
+
'MAY': '05', 'JUNE': '06', 'JULY': '07', 'AUGUST': '08',
|
|
103
|
+
'SEPTEMBER': '09', 'OCTOBER': '10', 'NOVEMBER': '11', 'DECEMBER': '12',
|
|
104
|
+
'JAN': '01', 'FEB': '02', 'MAR': '03', 'APR': '04',
|
|
105
|
+
'JUN': '06', 'JUL': '07', 'AUG': '08', 'SEP': '09', 'OCT': '10', 'NOV': '11', 'DEC': '12'
|
|
106
|
+
};
|
|
107
|
+
// Extract month, day, and year
|
|
108
|
+
const parts = dateStr.replace(',', '').split(' ');
|
|
109
|
+
const month = parts[0];
|
|
110
|
+
const day = parts[1];
|
|
111
|
+
const year = parts[2];
|
|
112
|
+
if (!monthMap[month]) {
|
|
113
|
+
console.error(`Unknown month: ${month} in date: ${dateStr}`);
|
|
114
|
+
throw new Error(`Unknown month: ${month} in date: ${dateStr}`);
|
|
115
|
+
}
|
|
116
|
+
date = new Date(`${year}-${monthMap[month]}-${day.padStart(2, '0')}`);
|
|
117
|
+
}
|
|
118
|
+
// Handle "DAY MONTH YEAR" format (e.g., "5 MARCH 2025")
|
|
119
|
+
else if (dateStr.match(/^\d{1,2} [A-Z]+ \d{4}$/)) {
|
|
120
|
+
const monthMap = {
|
|
121
|
+
'JANUARY': '01', 'FEBRUARY': '02', 'MARCH': '03', 'APRIL': '04',
|
|
122
|
+
'MAY': '05', 'JUNE': '06', 'JULY': '07', 'AUGUST': '08',
|
|
123
|
+
'SEPTEMBER': '09', 'OCTOBER': '10', 'NOVEMBER': '11', 'DECEMBER': '12',
|
|
124
|
+
'JAN': '01', 'FEB': '02', 'MAR': '03', 'APR': '04',
|
|
125
|
+
'JUN': '06', 'JUL': '07', 'AUG': '08', 'SEP': '09', 'OCT': '10', 'NOV': '11', 'DEC': '12'
|
|
126
|
+
};
|
|
127
|
+
const parts = dateStr.split(' ');
|
|
128
|
+
const day = parts[0];
|
|
129
|
+
const month = parts[1];
|
|
130
|
+
const year = parts[2];
|
|
131
|
+
if (!monthMap[month]) {
|
|
132
|
+
console.error(`Unknown month: ${month} in date: ${dateStr}`);
|
|
133
|
+
throw new Error(`Unknown month: ${month} in date: ${dateStr}`);
|
|
134
|
+
}
|
|
135
|
+
date = new Date(`${year}-${monthMap[month]}-${day.padStart(2, '0')}`);
|
|
136
|
+
}
|
|
137
|
+
if (!date || isNaN(date.getTime())) {
|
|
138
|
+
console.error(`Failed to parse date: ${dateStr}`);
|
|
139
|
+
// Fallback: try to use the JavaScript Date parser directly
|
|
140
|
+
const fallbackDate = new Date(dateStr);
|
|
141
|
+
if (!isNaN(fallbackDate.getTime())) {
|
|
142
|
+
console.log(`Fallback date parsing succeeded for: ${dateStr}`);
|
|
143
|
+
return fallbackDate.toISOString().split('T')[0];
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`Invalid date format: ${dateStr}`);
|
|
146
|
+
}
|
|
147
|
+
// Return in YYYY-MM-DD format
|
|
148
|
+
const formattedDate = date.toISOString().split('T')[0];
|
|
149
|
+
return formattedDate;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
console.error(`Error parsing date '${dateStr}':`, error);
|
|
153
|
+
// If all else fails, return null instead of today's date
|
|
154
|
+
console.log(`Unable to parse date: ${dateStr}, returning null`);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function convertCurrencySymbolToCode(symbol) {
|
|
159
|
+
if (!symbol || typeof symbol !== 'string') {
|
|
160
|
+
console.error(`Invalid currency input: ${symbol}`);
|
|
161
|
+
return 'USD'; // Default to USD
|
|
162
|
+
}
|
|
163
|
+
// console.log(`Converting currency symbol/name: "${symbol}"`);
|
|
164
|
+
// Clean up the input - remove whitespace and normalize
|
|
165
|
+
const cleanSymbol = symbol.trim().toUpperCase();
|
|
166
|
+
// Map of currency symbols and names to ISO codes
|
|
167
|
+
const currencyMap = {
|
|
168
|
+
// Symbols
|
|
169
|
+
'$': 'USD',
|
|
170
|
+
'£': 'GBP',
|
|
171
|
+
'€': 'EUR',
|
|
172
|
+
'¥': 'JPY',
|
|
173
|
+
'₽': 'RUB',
|
|
174
|
+
'₩': 'KRW',
|
|
175
|
+
'₿': 'BTC',
|
|
176
|
+
'CHF': 'CHF',
|
|
177
|
+
// Names and codes - USD
|
|
178
|
+
'USD': 'USD',
|
|
179
|
+
'DOLLAR': 'USD',
|
|
180
|
+
'DOLLARS': 'USD',
|
|
181
|
+
'US DOLLAR': 'USD',
|
|
182
|
+
'US DOLLARS': 'USD',
|
|
183
|
+
'U.S. DOLLAR': 'USD',
|
|
184
|
+
'U.S. DOLLARS': 'USD',
|
|
185
|
+
'UNITED STATES DOLLAR': 'USD',
|
|
186
|
+
// Names and codes - EUR
|
|
187
|
+
'EUR': 'EUR',
|
|
188
|
+
'EURO': 'EUR',
|
|
189
|
+
'EUROS': 'EUR',
|
|
190
|
+
'EUROPEAN EURO': 'EUR',
|
|
191
|
+
// Names and codes - GBP
|
|
192
|
+
'GBP': 'GBP',
|
|
193
|
+
'POUND': 'GBP',
|
|
194
|
+
'POUNDS': 'GBP',
|
|
195
|
+
'POUND STERLING': 'GBP',
|
|
196
|
+
'BRITISH POUND': 'GBP',
|
|
197
|
+
'UK POUND': 'GBP',
|
|
198
|
+
// Names and codes - JPY
|
|
199
|
+
'JPY': 'JPY',
|
|
200
|
+
'YEN': 'JPY',
|
|
201
|
+
'JAPANESE YEN': 'JPY',
|
|
202
|
+
// Other common currencies
|
|
203
|
+
'CAD': 'CAD',
|
|
204
|
+
'CANADIAN DOLLAR': 'CAD',
|
|
205
|
+
'CANADIAN DOLLARS': 'CAD',
|
|
206
|
+
};
|
|
207
|
+
// Check if the symbol is in our map
|
|
208
|
+
if (currencyMap[cleanSymbol]) {
|
|
209
|
+
// console.log(`Mapped currency "${symbol}" to "${currencyMap[cleanSymbol]}"`);
|
|
210
|
+
return currencyMap[cleanSymbol];
|
|
211
|
+
}
|
|
212
|
+
// Check if it's a 3-letter currency code
|
|
213
|
+
if (cleanSymbol.length === 3 && /^[A-Z]{3}$/.test(cleanSymbol)) {
|
|
214
|
+
// console.log(`Using 3-letter currency code as is: "${cleanSymbol}"`);
|
|
215
|
+
return cleanSymbol;
|
|
216
|
+
}
|
|
217
|
+
// Special case for "EURO" which should be "EUR"
|
|
218
|
+
if (cleanSymbol === 'EURO' || cleanSymbol === 'EUROS') {
|
|
219
|
+
// console.log(`Converting "${cleanSymbol}" to "EUR"`);
|
|
220
|
+
return 'EUR';
|
|
221
|
+
}
|
|
222
|
+
// console.log(`Unknown currency symbol/name: "${symbol}", defaulting to "USD"`);
|
|
223
|
+
return 'USD'; // Default to USD for unknown currencies
|
|
224
|
+
}
|
|
225
|
+
function normalizeChainName(chainName) {
|
|
226
|
+
// Convert to lowercase for case-insensitive comparison
|
|
227
|
+
const lowercaseName = chainName.toLowerCase();
|
|
228
|
+
// Map of known chain names (lowercase) to their standardized versions
|
|
229
|
+
const chainNameMap = {
|
|
230
|
+
'base': 'Base',
|
|
231
|
+
// Add more chain mappings as needed
|
|
232
|
+
'ethereum': 'Ethereum',
|
|
233
|
+
'polygon': 'Polygon',
|
|
234
|
+
'arbitrum': 'Arbitrum',
|
|
235
|
+
'optimism': 'Optimism',
|
|
236
|
+
'avalanche': 'Avalanche'
|
|
237
|
+
};
|
|
238
|
+
// Return the standardized name if found, otherwise return the original
|
|
239
|
+
return chainNameMap[lowercaseName] || chainName;
|
|
240
|
+
}
|
|
241
|
+
function normalizeAccountType(accountType) {
|
|
242
|
+
// Convert to lowercase for case-insensitive comparison
|
|
243
|
+
const lowercaseType = accountType.toLowerCase().trim();
|
|
244
|
+
// Map of account type variations to standardized versions
|
|
245
|
+
const accountTypeMap = {
|
|
246
|
+
'checking': 'CHECKING',
|
|
247
|
+
'check': 'CHECKING',
|
|
248
|
+
'chk': 'CHECKING',
|
|
249
|
+
'current': 'CHECKING', // Some countries call checking accounts "current accounts"
|
|
250
|
+
'savings': 'SAVINGS',
|
|
251
|
+
'saving': 'SAVINGS',
|
|
252
|
+
'save': 'SAVINGS',
|
|
253
|
+
'sav': 'SAVINGS'
|
|
254
|
+
};
|
|
255
|
+
// Return the standardized type if found, otherwise default to CHECKING
|
|
256
|
+
return accountTypeMap[lowercaseType] || 'CHECKING';
|
|
257
|
+
}
|
|
258
|
+
function parseAddress(addressText) {
|
|
259
|
+
// Split into lines and clean each line
|
|
260
|
+
let addressLines = addressText.split(/[,\n]/).map(line => line.trim()).filter(Boolean);
|
|
261
|
+
const addressData = {
|
|
262
|
+
streetAddress: '',
|
|
263
|
+
extendedAddress: null,
|
|
264
|
+
city: '',
|
|
265
|
+
postalCode: '',
|
|
266
|
+
stateProvince: '',
|
|
267
|
+
country: ''
|
|
268
|
+
};
|
|
269
|
+
// Helper function to identify common countries
|
|
270
|
+
const isLikelyCountry = (str) => {
|
|
271
|
+
const commonCountries = new Set([
|
|
272
|
+
'chile', 'portugal', 'philippines', 'germany', 'deutschland',
|
|
273
|
+
'usa', 'united states', 'us', 'canada', 'uk', 'united kingdom',
|
|
274
|
+
'australia', 'switzerland', 'france', 'spain', 'italy', 'ch', 'slovenia',
|
|
275
|
+
'slovakia', 'hungary', 'poland', 'czechia', 'czech republic', 'romania',
|
|
276
|
+
]);
|
|
277
|
+
return commonCountries.has(str.toLowerCase());
|
|
278
|
+
};
|
|
279
|
+
// Process lines in reverse order
|
|
280
|
+
for (let i = addressLines.length - 1; i >= 0; i--) {
|
|
281
|
+
let line = addressLines[i].trim();
|
|
282
|
+
if (!line)
|
|
283
|
+
continue;
|
|
284
|
+
// Check for labeled fields first
|
|
285
|
+
const zipMatch = line.match(/ZIP:\s*(\d+)/i);
|
|
286
|
+
const cantonMatch = line.match(/Canton:\s*(\w+)/i);
|
|
287
|
+
const countryMatch = line.match(/Country:\s*(\w+)/i);
|
|
288
|
+
if (zipMatch) {
|
|
289
|
+
addressData.postalCode = zipMatch[1];
|
|
290
|
+
line = line.replace(/ZIP:\s*\d+/i, '').trim();
|
|
291
|
+
}
|
|
292
|
+
if (cantonMatch) {
|
|
293
|
+
addressData.stateProvince = cantonMatch[1];
|
|
294
|
+
line = line.replace(/Canton:\s*\w+/i, '').trim();
|
|
295
|
+
}
|
|
296
|
+
if (countryMatch) {
|
|
297
|
+
addressData.country = countryMatch[1];
|
|
298
|
+
line = line.replace(/Country:\s*\w+/i, '').trim();
|
|
299
|
+
}
|
|
300
|
+
// If line is empty after removing labels, continue to next line
|
|
301
|
+
if (!line)
|
|
302
|
+
continue;
|
|
303
|
+
// Check if this line is a country
|
|
304
|
+
if (isLikelyCountry(line)) {
|
|
305
|
+
addressData.country = line;
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
// Check for postal code in remaining text
|
|
309
|
+
const postalCodeMatch = line.match(/\b\d{4,6}\b/);
|
|
310
|
+
if (postalCodeMatch && !addressData.postalCode) {
|
|
311
|
+
addressData.postalCode = postalCodeMatch[0];
|
|
312
|
+
line = line.replace(postalCodeMatch[0], '').trim();
|
|
313
|
+
}
|
|
314
|
+
// If we haven't set the city yet and this isn't the first line
|
|
315
|
+
if (!addressData.city && i > 0) {
|
|
316
|
+
addressData.city = line;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// First line handling
|
|
320
|
+
if (i === 0) {
|
|
321
|
+
addressData.streetAddress = line;
|
|
322
|
+
}
|
|
323
|
+
// Second line handling (if not already used for city)
|
|
324
|
+
else if (i === 1 && !addressData.city && line) {
|
|
325
|
+
// If we don't have a street address yet, this is probably it
|
|
326
|
+
if (!addressData.streetAddress) {
|
|
327
|
+
addressData.streetAddress = line;
|
|
328
|
+
}
|
|
329
|
+
// Otherwise, this might be extended address info
|
|
330
|
+
else if (line !== addressData.city) {
|
|
331
|
+
addressData.extendedAddress = line || null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Clean up data
|
|
336
|
+
const cleanupField = (str) => {
|
|
337
|
+
if (!str)
|
|
338
|
+
return '';
|
|
339
|
+
return str
|
|
340
|
+
.replace(/,+$/, '')
|
|
341
|
+
.replace(/\s+/g, ' ')
|
|
342
|
+
.trim();
|
|
343
|
+
};
|
|
344
|
+
// Handle special case where city might be in the country field
|
|
345
|
+
if (addressData.country && !addressData.city && addressData.country.toLowerCase() !== 'chile') {
|
|
346
|
+
const parts = addressData.country.split(/\s+/);
|
|
347
|
+
if (parts.length > 1) {
|
|
348
|
+
addressData.city = parts[0];
|
|
349
|
+
addressData.country = parts[parts.length - 1];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
streetAddress: cleanupField(addressData.streetAddress),
|
|
354
|
+
extendedAddress: addressData.extendedAddress,
|
|
355
|
+
city: cleanupField(addressData.city),
|
|
356
|
+
postalCode: cleanupField(addressData.postalCode),
|
|
357
|
+
stateProvince: cleanupField(addressData.stateProvince),
|
|
358
|
+
country: cleanupField(addressData.country)
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function parseNumber(value) {
|
|
362
|
+
if (!value || typeof value !== 'string') {
|
|
363
|
+
console.error(`Invalid number input: ${value}`);
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
366
|
+
// Clean the input
|
|
367
|
+
let cleanValue = value.trim();
|
|
368
|
+
// Detect format by looking at the decimal and thousand separators
|
|
369
|
+
const hasCommaDecimal = /\d,\d{2}$/.test(cleanValue); // e.g., "1.234,56" or "1234,56"
|
|
370
|
+
const hasDotDecimal = /\d\.\d{2}$/.test(cleanValue); // e.g., "1,234.56" or "1234.56"
|
|
371
|
+
if (hasCommaDecimal) {
|
|
372
|
+
// European format: convert "1.234,56" or "1234,56" to "1234.56"
|
|
373
|
+
cleanValue = cleanValue
|
|
374
|
+
.replace(/\./g, '') // Remove thousand separators
|
|
375
|
+
.replace(',', '.'); // Convert decimal separator
|
|
376
|
+
}
|
|
377
|
+
else if (hasDotDecimal) {
|
|
378
|
+
// Standard format: convert "1,234.56" or "1234.56" to "1234.56"
|
|
379
|
+
cleanValue = cleanValue.replace(/,/g, ''); // Remove thousand separators
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
// No decimal places - check for thousand separators
|
|
383
|
+
if (cleanValue.includes(',')) {
|
|
384
|
+
// If comma is thousand separator, remove it
|
|
385
|
+
cleanValue = cleanValue.replace(/,/g, '');
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const parsed = parseFloat(cleanValue);
|
|
389
|
+
if (isNaN(parsed)) {
|
|
390
|
+
console.error(`Failed to parse number: ${value}`);
|
|
391
|
+
return 0;
|
|
392
|
+
}
|
|
393
|
+
return parsed;
|
|
394
|
+
}
|
|
395
|
+
function mapDocumentAiToInvoice(entities, existingInvoice) {
|
|
396
|
+
const invoiceData = existingInvoice || {
|
|
397
|
+
lineItems: []
|
|
398
|
+
};
|
|
399
|
+
// 1. Initialize base issuer structure if it doesn't exist
|
|
400
|
+
if (!invoiceData.issuer) {
|
|
401
|
+
invoiceData.issuer = {
|
|
402
|
+
name: null,
|
|
403
|
+
address: null,
|
|
404
|
+
contactInfo: {
|
|
405
|
+
email: null,
|
|
406
|
+
tel: null
|
|
407
|
+
},
|
|
408
|
+
country: null,
|
|
409
|
+
id: null,
|
|
410
|
+
paymentRouting: null
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
// 2. Initialize base payer structure if it doesn't exist
|
|
414
|
+
if (!invoiceData.payer) {
|
|
415
|
+
invoiceData.payer = {
|
|
416
|
+
name: null,
|
|
417
|
+
address: null,
|
|
418
|
+
contactInfo: {
|
|
419
|
+
email: null,
|
|
420
|
+
tel: null
|
|
421
|
+
},
|
|
422
|
+
country: null,
|
|
423
|
+
id: null,
|
|
424
|
+
paymentRouting: null
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
// 3. Initialize payment routing structure once if needed
|
|
428
|
+
if (!invoiceData.issuer.paymentRouting) {
|
|
429
|
+
invoiceData.issuer.paymentRouting = {
|
|
430
|
+
bank: {
|
|
431
|
+
name: "",
|
|
432
|
+
accountNum: "",
|
|
433
|
+
ABA: "",
|
|
434
|
+
BIC: "",
|
|
435
|
+
SWIFT: "",
|
|
436
|
+
accountType: "CHECKING",
|
|
437
|
+
beneficiary: "",
|
|
438
|
+
memo: "",
|
|
439
|
+
address: {
|
|
440
|
+
streetAddress: "",
|
|
441
|
+
city: "",
|
|
442
|
+
stateProvince: "",
|
|
443
|
+
postalCode: "",
|
|
444
|
+
country: "",
|
|
445
|
+
extendedAddress: ""
|
|
446
|
+
},
|
|
447
|
+
intermediaryBank: null
|
|
448
|
+
},
|
|
449
|
+
wallet: {
|
|
450
|
+
address: "",
|
|
451
|
+
chainId: "",
|
|
452
|
+
chainName: "",
|
|
453
|
+
rpc: ""
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
// 4. Process all entities and update the single payment routing object
|
|
458
|
+
entities.forEach(entity => {
|
|
459
|
+
switch (entity.type) {
|
|
460
|
+
// Handle new schema format for bank details
|
|
461
|
+
case 'supplier_bank_name':
|
|
462
|
+
invoiceData.issuer.paymentRouting.bank.name = entity.mentionText;
|
|
463
|
+
break;
|
|
464
|
+
case 'supplier_bank_account_type':
|
|
465
|
+
invoiceData.issuer.paymentRouting.bank.accountType = normalizeAccountType(entity.mentionText);
|
|
466
|
+
break;
|
|
467
|
+
case 'supplier_aba_swift_bic_number':
|
|
468
|
+
const bankCode = entity.mentionText.replace(/^[:.\s]+/, '').trim();
|
|
469
|
+
if (invoiceData.issuer?.paymentRouting?.bank) {
|
|
470
|
+
// Set both BIC and SWIFT since they're typically the same
|
|
471
|
+
invoiceData.issuer.paymentRouting.bank.BIC = bankCode;
|
|
472
|
+
invoiceData.issuer.paymentRouting.bank.SWIFT = bankCode;
|
|
473
|
+
}
|
|
474
|
+
break;
|
|
475
|
+
case 'supplier_bank_address':
|
|
476
|
+
const bankAddress = parseAddress(entity.mentionText);
|
|
477
|
+
if (invoiceData.issuer?.paymentRouting?.bank) {
|
|
478
|
+
invoiceData.issuer.paymentRouting.bank.address = bankAddress;
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
481
|
+
// Handle existing cases for crypto details
|
|
482
|
+
case 'crypto_account_details':
|
|
483
|
+
entity.children?.forEach(child => {
|
|
484
|
+
const wallet = invoiceData.issuer.paymentRouting.wallet;
|
|
485
|
+
switch (child.type) {
|
|
486
|
+
case 'crypto_account_details/account_address':
|
|
487
|
+
let address = child.mentionText;
|
|
488
|
+
if (address.startsWith('Ox')) {
|
|
489
|
+
address = '0x' + address.slice(2);
|
|
490
|
+
}
|
|
491
|
+
wallet.address = address;
|
|
492
|
+
break;
|
|
493
|
+
case 'crypto_account_details/chain_name':
|
|
494
|
+
wallet.chainName = normalizeChainName(child.mentionText);
|
|
495
|
+
break;
|
|
496
|
+
case 'crypto_account_details/chain_id':
|
|
497
|
+
wallet.chainId = child.mentionText;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
break;
|
|
502
|
+
case 'supplier_iban':
|
|
503
|
+
invoiceData.issuer.paymentRouting.bank.accountNum = entity.mentionText;
|
|
504
|
+
break;
|
|
505
|
+
case 'invoice_id':
|
|
506
|
+
invoiceData.invoiceNo = entity.mentionText;
|
|
507
|
+
break;
|
|
508
|
+
case 'invoice_date':
|
|
509
|
+
invoiceData.dateIssued = parseDate(entity.mentionText) || undefined;
|
|
510
|
+
break;
|
|
511
|
+
case 'due_date':
|
|
512
|
+
invoiceData.dateDue = parseDate(entity.mentionText) || undefined;
|
|
513
|
+
break;
|
|
514
|
+
case 'currency':
|
|
515
|
+
const currencyCode = convertCurrencySymbolToCode(entity.mentionText);
|
|
516
|
+
console.log(`Setting invoice currency to: ${currencyCode} (from ${entity.mentionText})`);
|
|
517
|
+
invoiceData.currency = currencyCode;
|
|
518
|
+
// Also update currency in line items if they exist
|
|
519
|
+
if (invoiceData.lineItems && invoiceData.lineItems.length > 0) {
|
|
520
|
+
invoiceData.lineItems = invoiceData.lineItems.map(item => ({
|
|
521
|
+
...item,
|
|
522
|
+
currency: currencyCode
|
|
523
|
+
}));
|
|
524
|
+
console.log(`Updated currency in ${invoiceData.lineItems.length} line items to ${currencyCode}`);
|
|
525
|
+
}
|
|
526
|
+
break;
|
|
527
|
+
case 'supplier_name':
|
|
528
|
+
invoiceData.issuer.name = entity.mentionText;
|
|
529
|
+
// Set beneficiary name to supplier name only if no remit_to_name was found
|
|
530
|
+
if (invoiceData.issuer?.paymentRouting?.bank && !invoiceData.issuer.paymentRouting.bank.beneficiary) {
|
|
531
|
+
invoiceData.issuer.paymentRouting.bank.beneficiary = entity.mentionText;
|
|
532
|
+
}
|
|
533
|
+
break;
|
|
534
|
+
case 'remit_to_name':
|
|
535
|
+
// Set the bank beneficiary name (this will override any supplier name that was set)
|
|
536
|
+
if (invoiceData.issuer?.paymentRouting?.bank) {
|
|
537
|
+
invoiceData.issuer.paymentRouting.bank.beneficiary = entity.mentionText;
|
|
538
|
+
}
|
|
539
|
+
// If supplier name is not set, use remit_to_name as a fallback
|
|
540
|
+
if (!invoiceData.issuer.name) {
|
|
541
|
+
invoiceData.issuer.name = entity.mentionText;
|
|
542
|
+
}
|
|
543
|
+
break;
|
|
544
|
+
case 'supplier_email':
|
|
545
|
+
if (!invoiceData.issuer.contactInfo) {
|
|
546
|
+
invoiceData.issuer.contactInfo = { email: null, tel: null };
|
|
547
|
+
}
|
|
548
|
+
invoiceData.issuer.contactInfo.email = entity.mentionText;
|
|
549
|
+
break;
|
|
550
|
+
case 'supplier_address':
|
|
551
|
+
const supplierAddress = parseAddress(entity.mentionText);
|
|
552
|
+
invoiceData.issuer.address = supplierAddress;
|
|
553
|
+
if (supplierAddress.country) {
|
|
554
|
+
invoiceData.issuer.country = supplierAddress.country;
|
|
555
|
+
}
|
|
556
|
+
break;
|
|
557
|
+
case 'supplier_tax_id':
|
|
558
|
+
invoiceData.issuer.id = {
|
|
559
|
+
taxId: entity.mentionText
|
|
560
|
+
};
|
|
561
|
+
break;
|
|
562
|
+
case 'supplier_phone':
|
|
563
|
+
if (!invoiceData.issuer.contactInfo) {
|
|
564
|
+
invoiceData.issuer.contactInfo = { email: null, tel: null };
|
|
565
|
+
}
|
|
566
|
+
invoiceData.issuer.contactInfo.tel = entity.mentionText;
|
|
567
|
+
break;
|
|
568
|
+
case 'line_item':
|
|
569
|
+
const quantity = entity.children?.find(child => child.type === 'line_item/quantity')?.mentionText || '';
|
|
570
|
+
const unitPrice = entity.children?.find(child => child.type === 'line_item/unit_price')?.mentionText || '';
|
|
571
|
+
const description = entity.children?.find(child => child.type === 'line_item/description')?.mentionText || '';
|
|
572
|
+
if (quantity && unitPrice) {
|
|
573
|
+
const parsedQuantity = parseNumber(quantity);
|
|
574
|
+
const parsedUnitPrice = parseNumber(unitPrice);
|
|
575
|
+
console.log(`Parsed quantity: ${quantity} -> ${parsedQuantity}`);
|
|
576
|
+
console.log(`Parsed unit price: ${unitPrice} -> ${parsedUnitPrice}`);
|
|
577
|
+
// Only add line item if all required fields are present and valid
|
|
578
|
+
if (description && quantity && unitPrice) {
|
|
579
|
+
const parsedQuantity = parseNumber(quantity);
|
|
580
|
+
const parsedUnitPrice = parseNumber(unitPrice);
|
|
581
|
+
// Additional check to ensure parsed values are valid numbers
|
|
582
|
+
if (!isNaN(parsedQuantity) && !isNaN(parsedUnitPrice)) {
|
|
583
|
+
invoiceData.lineItems = invoiceData.lineItems || [];
|
|
584
|
+
invoiceData.lineItems.push({
|
|
585
|
+
lineItemTag: [],
|
|
586
|
+
description,
|
|
587
|
+
quantity: parsedQuantity,
|
|
588
|
+
unitPriceTaxExcl: parsedUnitPrice,
|
|
589
|
+
unitPriceTaxIncl: parsedUnitPrice,
|
|
590
|
+
totalPriceTaxExcl: parsedQuantity * parsedUnitPrice,
|
|
591
|
+
totalPriceTaxIncl: parsedQuantity * parsedUnitPrice,
|
|
592
|
+
currency: invoiceData.currency || 'USD',
|
|
593
|
+
id: crypto.randomUUID(),
|
|
594
|
+
taxPercent: 0
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
break;
|
|
600
|
+
// Handle receiver (payer) information
|
|
601
|
+
case 'receiver_name':
|
|
602
|
+
if (!invoiceData.payer) {
|
|
603
|
+
invoiceData.payer = {
|
|
604
|
+
name: entity.mentionText,
|
|
605
|
+
address: null,
|
|
606
|
+
contactInfo: { email: null, tel: null },
|
|
607
|
+
country: null,
|
|
608
|
+
id: null,
|
|
609
|
+
paymentRouting: null
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
invoiceData.payer.name = entity.mentionText;
|
|
614
|
+
}
|
|
615
|
+
break;
|
|
616
|
+
case 'receiver_address':
|
|
617
|
+
const receiverAddress = parseAddress(entity.mentionText);
|
|
618
|
+
invoiceData.payer.address = receiverAddress;
|
|
619
|
+
if (receiverAddress.country) {
|
|
620
|
+
invoiceData.payer.country = receiverAddress.country;
|
|
621
|
+
}
|
|
622
|
+
break;
|
|
623
|
+
case 'receiver_email':
|
|
624
|
+
if (!invoiceData.payer.contactInfo) {
|
|
625
|
+
invoiceData.payer.contactInfo = { email: null, tel: null };
|
|
626
|
+
}
|
|
627
|
+
invoiceData.payer.contactInfo.email = entity.mentionText;
|
|
628
|
+
break;
|
|
629
|
+
case 'receiver_tax_id':
|
|
630
|
+
if (!invoiceData.payer.id) {
|
|
631
|
+
invoiceData.payer.id = {
|
|
632
|
+
taxId: entity.mentionText
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
invoiceData.payer.id = {
|
|
637
|
+
taxId: entity.mentionText
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
break;
|
|
641
|
+
case 'total_amount':
|
|
642
|
+
const totalAmount = parseNumber(entity.mentionText);
|
|
643
|
+
invoiceData.totalPriceTaxExcl = totalAmount;
|
|
644
|
+
invoiceData.totalPriceTaxIncl = totalAmount; // Assuming no tax for now
|
|
645
|
+
break;
|
|
646
|
+
case 'vat':
|
|
647
|
+
const taxRate = parseNumber(entity.mentionText) || 0;
|
|
648
|
+
// Apply tax rate to line items
|
|
649
|
+
if (invoiceData.lineItems) {
|
|
650
|
+
invoiceData.lineItems = invoiceData.lineItems.map(item => ({
|
|
651
|
+
...item,
|
|
652
|
+
taxPercent: taxRate
|
|
653
|
+
}));
|
|
654
|
+
}
|
|
655
|
+
break;
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
return invoiceData;
|
|
659
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestFinance.d.ts","sourceRoot":"","sources":["../../../scripts/invoice/requestFinance.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,GAAU,aAAa,GAAG,iBA0C1D,CAAC"}
|