UNPKG

@logismix/mydata-client

Version:
317 lines (316 loc) 13.9 kB
"use strict"; // Using browser-native fetch API and URLSearchParams Object.defineProperty(exports, "__esModule", { value: true }); exports.MyDataClient = void 0; const constants_1 = require("../constants"); const xml_helper_1 = require("./internal/xml-helper"); const utils_1 = require("./internal/utils"); /** * MyDATA API Service (Browser & Node.js compatible) * * This service provides functions for interacting with the Greek myDATA API for both ERP and Provider users. */ class MyDataClient { get erpBaseUrl() { return this._production ? constants_1.MYDATA_ERP_BASE_URL : constants_1.MYDATA_DEV_ERP_BASE_URL; } get providerBaseUrl() { return this._production ? constants_1.MYDATA_PROVIDER_BASE_URL : constants_1.MYDATA_DEV_PROVIDER_BASE_URL; } constructor(initConfig) { this._xmlService = new xml_helper_1.XmlHelper(); this._production = false; this._userId = initConfig.userId; this._subscriptionKey = initConfig.subscriptionKey; this._production = !!initConfig.production; if (!this._userId || !this._subscriptionKey) { throw new Error('userId and subscriptionKey must be provided in the config'); } } getHeaders(isXmlContent = true) { const headers = new Headers(); headers.set('aade-user-id', this._userId); headers.set('ocp-apim-subscription-key', this._subscriptionKey); if (isXmlContent) { headers.set('Content-Type', 'application/xml'); } return headers; } async handleResponse(response, context) { if (!response.ok) { const errorText = await response.text(); console.error(`myDATA API Error (${context}): ${response.status} ${response.statusText}\n${errorText}`); throw new Error(`Failed during ${context}: ${response.status} ${response.statusText}`); } const xmlResponse = await response.text(); const jsResponse = await this._xmlService.parseXml(xmlResponse); return jsResponse; } /** * [ERP] Sends one or more invoices, including corrected/amending ones. * @param invoices Array of invoice objects * @returns The full ResponseDoc from myDATA */ async sendErpInvoices(invoices) { const xml = this._xmlService.buildInvoicesDocXml(invoices); console.log('[ERP] Sending Invoices...'); const response = await fetch(`${this.erpBaseUrl}/SendInvoices`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendErpInvoices'); } /** * [ERP] Sends one or more income classifications, corresponding to already submitted invoices. * @param classificationsDoc Object containing income classifications * @returns The full ResponseDoc from myDATA */ async sendErpIncomeClassification(classificationsDoc) { const xml = this._xmlService.buildIncomeClassificationXml(classificationsDoc); console.log('[ERP] Sending Income Classifications...'); const response = await fetch(`${this.erpBaseUrl}/SendIncomeClassification`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendErpIncomeClassification'); } /** * [ERP] Sends one or more expense classifications. * @param classificationsDoc Object containing classifications * @returns The full ResponseDoc from myDATA */ async sendErpExpensesClassification(classificationsDoc) { const xml = this._xmlService.buildExpensesClassificationXml(classificationsDoc); console.log('[ERP] Sending Expense Classifications...'); const response = await fetch(`${this.erpBaseUrl}/SendExpensesClassification`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendErpExpensesClassification'); } /** * [ERP] Sends payment methods for an invoice. * @param paymentsDoc Object containing payment methods * @returns The full ResponseDoc from myDATA */ async sendErpPaymentsMethod(paymentsDoc) { const xml = this._xmlService.buildPaymentMethodsXml(paymentsDoc); console.log('[ERP] Sending Payment Methods...'); const response = await fetch(`${this.erpBaseUrl}/SendPaymentsMethod`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendErpPaymentsMethod'); } /** * [ERP] Cancels a previously transmitted invoice. * @param mark The MARK of the invoice to cancel * @param entityVatNumber Optional: VAT of the entity if called by a representative * @returns The full ResponseDoc from myDATA (containing cancellationMark on success) */ async cancelErpInvoice(mark, entityVatNumber) { const params = (0, utils_1.requestParamsToUrlParams)({ mark, entityVatNumber }); const url = `${this.erpBaseUrl}/CancelInvoice?${params.toString()}`; console.log(`[ERP] Cancelling Invoice MARK: ${mark}...`); const response = await fetch(url, { method: 'POST', // API Doc specifies POST, even with query params headers: this.getHeaders(false), // No XML body body: undefined // Send no body }); return this.handleResponse(response, 'cancelErpInvoice'); } /** * [ERP] Requests documents (invoices, classifications, cancellations) received from others. * @param params Search parameters * @returns Parsed RequestedDoc object */ async requestErpDocs(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestDocs?${queryParams.toString()}`; console.log('[ERP] Requesting Received Docs...'); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <req:RequestedDoc> root return this.handleResponse(response, 'requestErpDocs'); } /** * [ERP] Requests documents (invoices, classifications, cancellations) previously transmitted by the user. * @param params Search parameters * @returns Parsed RequestedDoc object */ async requestErpTransmittedDocs(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestTransmittedDocs?${queryParams.toString()}`; console.log('[ERP] Requesting Transmitted Docs...', url); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <req:RequestedDoc> root return this.handleResponse(response, 'requestErpTransmittedDocs'); } /** * [ERP] Requests aggregated income data for a period. * @param params Search parameters (dateFrom, dateTo required) * @returns Parsed RequestedBookInfo object */ async requestErpMyIncome(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestMyIncome?${queryParams.toString()}`; console.log('[ERP] Requesting MyIncome...'); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <reqbi:RequestedBookInfo> root return this.handleResponse(response, 'requestErpMyIncome'); } /** * [ERP] Requests aggregated expense data for a period. * @param params Search parameters (dateFrom, dateTo required) * @returns Parsed RequestedBookInfo object */ async requestErpMyExpenses(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestMyExpenses?${queryParams.toString()}`; console.log('[ERP] Requesting MyExpenses...'); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <reqbi:RequestedBookInfo> root return this.handleResponse(response, 'requestErpMyExpenses'); } /** * [ERP] Requests VAT related data for a period. * @param params Search parameters (dateFrom, dateTo required) * @returns Parsed RequestedVatInfo object */ async requestErpVatInfo(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestVatInfo?${queryParams.toString()}`; console.log('[ERP] Requesting VatInfo...'); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <reqvi:RequestedVatInfo> root return this.handleResponse(response, 'requestErpVatInfo'); } /** * [ERP] Requests E3 related data for a period. * @param params Search parameters (dateFrom, dateTo required) * @returns Parsed RequestedE3Info object */ async requestErpE3Info(params) { const queryParams = (0, utils_1.requestParamsToUrlParams)(params); const url = `${this.erpBaseUrl}/RequestE3Info?${queryParams.toString()}`; console.log('[ERP] Requesting E3Info...'); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <RequestedE3Info> root return this.handleResponse(response, 'requestErpE3Info'); } // --- Provider User Methods --- /** * [Provider] Sends one or more invoices. * @param invoices Array of invoice objects * @returns The full ResponseDoc from myDATA */ async sendProviderInvoices(invoices) { const xml = this._xmlService.buildInvoicesDocXml(invoices); // Reuses ERP version // console.log('[Provider] Sending Invoices...', xml); const response = await fetch(`${this.providerBaseUrl}/SendInvoices`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendProviderInvoices'); } /** * [Provider] Sends one or more invoices pending issuance (unsigned). * @param invoices Array of invoice objects * @returns The full ResponseDoc from myDATA */ async sendProviderUnsignedInvoices(invoices) { const xml = this._xmlService.buildInvoicesDocXml(invoices); console.log('[Provider] Sending Unsigned Invoices...'); const response = await fetch(`${this.providerBaseUrl}/SendUnsignedInvoices`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendProviderUnsignedInvoices'); } /** * [Provider] Sends payment methods for an invoice. * @param paymentsDoc Object containing payment methods * @returns The full ResponseDoc from myDATA */ async sendProviderPaymentsMethod(paymentsDoc) { const xml = this._xmlService.buildPaymentMethodsXml(paymentsDoc); console.log('[Provider] Sending Payment Methods...'); const response = await fetch(`${this.providerBaseUrl}/SendPaymentsMethod`, { method: 'POST', headers: this.getHeaders(), body: xml }); return this.handleResponse(response, 'sendProviderPaymentsMethod'); } /** * [Provider] Requests summaries of documents previously transmitted by the provider for a specific issuer. * @param issuerVat The VAT number of the issuer whose invoices were sent * @param mark The minimum MARK to retrieve (exclusive) * @param nextPartitionKey Optional key for pagination * @param nextRowKey Optional key for pagination * @returns Parsed RequestedProviderDoc object */ async requestProviderTransmittedDocs(issuerVat, mark, nextPartitionKey, nextRowKey) { const params = (0, utils_1.requestParamsToUrlParams)({ issuerVat, mark, nextPartitionKey, nextRowKey }); const url = `${this.providerBaseUrl}/RequestTransmittedDocs?${params.toString()}`; console.log(`[Provider] Requesting Transmitted Docs for VAT ${issuerVat}... url=${url}`); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <RequestedProviderDoc> root return this.handleResponse(response, 'requestProviderTransmittedDocs'); } /** * [Provider] Requests information about a recipient's registered providers and emails. * @param vatNumber The VAT number of the recipient entity to query * @returns Parsed ReceiverInfoDoc object */ async requestProviderReceiverInfo(vatNumber) { const params = (0, utils_1.requestParamsToUrlParams)({ vatNumber }); const url = `${this.providerBaseUrl}/RequestReceiverInfo?${params.toString()}`; console.log(`[Provider] Requesting Receiver Info for VAT ${vatNumber}...`); const response = await fetch(url, { method: 'GET', headers: this.getHeaders(false) }); // TODO: Ensure XmlService.parseXml handles <ReceiverInfoDoc> root return this.handleResponse(response, 'requestProviderReceiverInfo'); } } exports.MyDataClient = MyDataClient;