@logismix/mydata-client
Version:
Greek myDATA (AADE) API client library
317 lines (316 loc) • 13.9 kB
JavaScript
"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;