UNPKG

@memberjunction/actions-bizapps-accounting

Version:

Accounting system integration actions for MemberJunction

184 lines 7.51 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BusinessCentralBaseAction = void 0; const global_1 = require("@memberjunction/global"); const base_accounting_action_1 = require("../../base/base-accounting-action"); const actions_1 = require("@memberjunction/actions"); /** * Base class for all Microsoft Dynamics 365 Business Central actions. * Handles BC-specific authentication and API interaction patterns. */ let BusinessCentralBaseAction = class BusinessCentralBaseAction extends base_accounting_action_1.BaseAccountingAction { accountingProvider = 'Business Central'; integrationName = 'Microsoft Dynamics 365 Business Central'; /** * Business Central API version */ apiVersion = 'v2.0'; /** * Makes an authenticated request to Business Central API */ async makeBCRequest(endpoint, method = 'GET', body, contextUser) { if (!contextUser) { throw new Error('Context user is required for Business Central API calls'); } // Get company ID from action params const companyId = this.getParamValue(this.params, 'CompanyID'); if (!companyId) { throw new Error('CompanyID parameter is required'); } // Get the integration credentials const integration = await this.getCompanyIntegration(companyId, contextUser); // Get OAuth tokens (from env vars or database) const { accessToken } = await this.getOAuthTokens(integration); // Get Business Central environment and company info const environment = integration.CustomAttribute1 || 'production'; const bcCompanyId = integration.ExternalSystemID; const tenantId = integration.CustomAttribute1 || this.getCredentialFromEnv(companyId, 'TENANT_ID'); if (!bcCompanyId) { throw new Error('Business Central Company ID not found. Set in CompanyIntegration.ExternalSystemID'); } if (!tenantId) { throw new Error('Tenant ID not found. Set in CompanyIntegration.CustomAttribute1 or environment variable'); } // Build the full URL const baseUrl = await this.getBusinessCentralAPIUrl(integration, tenantId, environment); const fullUrl = `${baseUrl}/companies(${bcCompanyId})/${endpoint}`; // Prepare headers const headers = { 'Authorization': `Bearer ${accessToken}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }; // Add API version header headers['api-version'] = this.apiVersion; try { const response = await fetch(fullUrl, { method, headers, body: body ? JSON.stringify(body) : undefined }); if (!response.ok) { const errorText = await response.text(); let errorMessage = `Business Central API error: ${response.status} ${response.statusText}`; try { const errorJson = JSON.parse(errorText); if (errorJson.error) { errorMessage = `Business Central API error: ${errorJson.error.message} (Code: ${errorJson.error.code})`; } } catch { errorMessage += ` - ${errorText}`; } throw new Error(errorMessage); } const result = await response.json(); return result; } catch (error) { if (error instanceof Error) { throw error; } throw new Error(`Business Central API request failed: ${error}`); } } /** * Handles Business Central OData queries */ async queryBC(resource, filters, select, expand, orderBy, top, contextUser) { const queryParams = []; if (filters && filters.length > 0) { queryParams.push(`$filter=${filters.join(' and ')}`); } if (select && select.length > 0) { queryParams.push(`$select=${select.join(',')}`); } if (expand && expand.length > 0) { queryParams.push(`$expand=${expand.join(',')}`); } if (orderBy) { queryParams.push(`$orderby=${orderBy}`); } if (top) { queryParams.push(`$top=${top}`); } const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''; return this.makeBCRequest(`${resource}${queryString}`, 'GET', undefined, contextUser); } /** * Formats date for Business Central API (ISO 8601) */ formatBCDate(date) { return date.toISOString().split('T')[0]; } /** * Parses Business Central date format */ parseBCDate(dateString) { return new Date(dateString); } /** * Maps Business Central account types to standard categories */ mapAccountType(bcAccountType) { const typeMap = { 'Posting': 'Posting', 'Heading': 'Header', 'Total': 'Total', 'Begin-Total': 'Subtotal', 'End-Total': 'Subtotal' }; return typeMap[bcAccountType] || 'Other'; } /** * Maps Business Central account category to standard type */ mapAccountCategory(category) { const categoryMap = { 'Assets': 'Asset', 'Liabilities': 'Liability', 'Equity': 'Equity', 'Income': 'Revenue', 'Cost of Goods Sold': 'Expense', 'Expense': 'Expense' }; return categoryMap[category] || 'Other'; } /** * Gets the appropriate Business Central API URL */ async getBusinessCentralAPIUrl(integration, tenantId, environment) { // Default Business Central API URL pattern // Format: https://api.businesscentral.dynamics.com/v2.0/{tenant-id}/{environment}/api/v2.0 return `https://api.businesscentral.dynamics.com/v2.0/${tenantId}/${environment}/api/${this.apiVersion}`; } /** * Helper to build OData filter expressions */ buildFilterExpression(field, operator, value) { if (typeof value === 'string') { return `${field} ${operator} '${value}'`; } else if (value instanceof Date) { return `${field} ${operator} ${value.toISOString()}`; } else { return `${field} ${operator} ${value}`; } } /** * Current action parameters (set by the framework) */ params; }; exports.BusinessCentralBaseAction = BusinessCentralBaseAction; exports.BusinessCentralBaseAction = BusinessCentralBaseAction = __decorate([ (0, global_1.RegisterClass)(actions_1.BaseAction, 'BusinessCentralBaseAction') ], BusinessCentralBaseAction); //# sourceMappingURL=business-central-base.action.js.map