UNPKG

@accounter/server

Version:

147 lines • 6.18 kB
import { __decorate, __metadata, __param } from "tslib"; import { CONTEXT, Inject, Injectable, Scope } from 'graphql-modules'; import { init } from '../../../../green-invoice-graphql/src/index.js'; import { dateToTimelessDateString } from '../../shared/helpers/index.js'; import { ENVIRONMENT } from '../../shared/tokens.js'; let GreenInvoiceProvider = class GreenInvoiceProvider { context; env; localCurrency; constructor(context, env) { this.context = context; this.env = env; this.localCurrency = this.context.adminContext.defaultLocalCurrency; } authToken = null; async init() { const id = this.env.greenInvoice.id; const secret = this.env.greenInvoice.secret; if (!id || !secret) { throw new Error('Environment variables not found'); } const greenInvoice = await init(id, secret); return greenInvoice; } async getSDK() { try { const { sdk, authToken } = await this.init(); this.authToken = authToken; return sdk; } catch (e) { console.error(e); throw new Error(`Green Invoice error: ${e.message}`); } } async addExpenseDraftByFile(file) { try { // convert what-wg file to nodejs file const newFile = new File([Buffer.from(await file.arrayBuffer())], 'name' in file ? file.name : 'new-file', { type: file.type, }); // get file upload url + params const sdk = await this.getSDK(); const { getFileUploadUrl: fileUploadParams } = await sdk.getFileUploadUrl_query({ context: 'expense', data: { source: 5 }, }); if (!fileUploadParams) { throw new Error('No file upload params returned'); } const form = new FormData(); for (const [field, value] of Object.entries(fileUploadParams.fields)) { if (value) { // replace field names underscores with dashes (originally dashes, Mesh converted to underscores to match GraphQL spec) form.append(field.replaceAll('_', '-'), value); } } form.append('file', newFile, newFile.name); const uploadTime = new Date().getTime(); // upload the file await fetch(fileUploadParams.url, { method: 'POST', body: form, }).then(async (res) => { if (![200, 201, 204].includes(res.status)) { throw new Error('Failed to upload file'); } return; }); // TODO: next section is temporary fix until decent webhook will be set up let retryCounter = 15; // 30 seconds while (retryCounter > 0) { await new Promise(resolve => setTimeout(resolve, 2000)); // 2 second delay to allow Green Invoice to process the file. const res = await sdk.searchExpenseDrafts_query({ input: { fromDate: dateToTimelessDateString(new Date()), toDate: dateToTimelessDateString(new Date()), }, }); if (res.searchExpenseDrafts && 'items' in res.searchExpenseDrafts && res.searchExpenseDrafts.items.length) { const items = res.searchExpenseDrafts.items.filter(item => { return !!item && item?.creationDate > uploadTime / 1000; }); if (items.length > 1) { // currently we cannot differentiate between drafts throw new Error('Multiple drafts found'); } if (items.length === 1) { const { expense } = items[0]; // check if any actual OCR fields exists if (expense.amount !== null || expense.currency !== this.localCurrency || expense.date !== null || expense.documentType !== '_20' || expense.number !== null || expense.vat !== 0) { console.log(`Finally, it took only ${(15 - retryCounter) * 2} seconds...`); return items[0]; } } } retryCounter -= 1; } console.log('Failed to fetch OCR data, returning empty draft'); const emptyDraft = { expense: { documentType: '_405', // "receipt on donation" which is not supported, resulting in unprocessed document number: undefined, date: undefined, amount: 0, currency: this.localCurrency, vat: 0, }, }; return emptyDraft; } catch (e) { console.error(e); throw new Error(`Green Invoice error: ${e.message}`); } } async searchDocuments(...params) { const sdk = await this.getSDK(); return sdk.searchDocuments_query(...params).then(res => res.searchDocuments); } async addDocuments(...params) { const sdk = await this.getSDK(); return sdk.addDocument_mutation(...params).then(res => res.addDocument); } async previewDocuments(...params) { const sdk = await this.getSDK(); return sdk.previewDocument_query(...params).then(res => res.previewDocument); } }; GreenInvoiceProvider = __decorate([ Injectable({ scope: Scope.Operation, global: true, }), __param(0, Inject(CONTEXT)), __param(1, Inject(ENVIRONMENT)), __metadata("design:paramtypes", [Object, Object]) ], GreenInvoiceProvider); export { GreenInvoiceProvider }; //# sourceMappingURL=green-invoice.js.map