@memberjunction/actions-bizapps-accounting
Version:
Accounting system integration actions for MemberJunction
303 lines • 12.2 kB
JavaScript
;
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.GetBusinessCentralGeneralLedgerEntriesAction = void 0;
const global_1 = require("@memberjunction/global");
const business_central_base_action_1 = require("../business-central-base.action");
const actions_1 = require("@memberjunction/actions");
/**
* Action to retrieve General Ledger Entries from Microsoft Dynamics 365 Business Central
*/
let GetBusinessCentralGeneralLedgerEntriesAction = class GetBusinessCentralGeneralLedgerEntriesAction extends business_central_base_action_1.BusinessCentralBaseAction {
/**
* Description of the action
*/
get Description() {
return 'Retrieves General Ledger Entries (journal entries) from Microsoft Dynamics 365 Business Central';
}
/**
* Main execution method
*/
async InternalRunAction(params) {
try {
const contextUser = params.ContextUser;
if (!contextUser) {
return {
Success: false,
ResultCode: 'ERROR',
Message: 'Context user is required for Business Central API calls'
};
}
// Store params for base class methods
this.params = params.Params;
// Build filters based on parameters
const filters = [];
// Date range filters
const startDate = this.getParamValue(params.Params, 'StartDate');
if (startDate) {
filters.push(`postingDate ge ${this.formatBCDate(new Date(startDate))}`);
}
const endDate = this.getParamValue(params.Params, 'EndDate');
if (endDate) {
filters.push(`postingDate le ${this.formatBCDate(new Date(endDate))}`);
}
// Account filter
const accountNumber = this.getParamValue(params.Params, 'AccountNumber');
if (accountNumber) {
filters.push(`accountNumber eq '${accountNumber}'`);
}
// Document number filter
const documentNumber = this.getParamValue(params.Params, 'DocumentNumber');
if (documentNumber) {
filters.push(`documentNumber eq '${documentNumber}'`);
}
// Document type filter
const documentType = this.getParamValue(params.Params, 'DocumentType');
if (documentType) {
filters.push(`documentType eq '${documentType}'`);
}
// Amount filters
const minAmount = this.getParamValue(params.Params, 'MinAmount');
if (minAmount !== undefined) {
filters.push(`amount ge ${minAmount}`);
}
const maxAmount = this.getParamValue(params.Params, 'MaxAmount');
if (maxAmount !== undefined) {
filters.push(`amount le ${maxAmount}`);
}
// Select fields to retrieve
const select = [
'id',
'entryNumber',
'postingDate',
'documentNumber',
'documentType',
'accountId',
'accountNumber',
'description',
'debitAmount',
'creditAmount',
'amount',
'lastModifiedDateTime'
];
// Expand dimensions if requested
const expand = [];
const includeDimensions = this.getParamValue(params.Params, 'IncludeDimensions');
if (includeDimensions) {
expand.push('dimensionSetLines');
}
// Order by
const orderBy = 'postingDate desc,entryNumber desc';
// Max results
const maxResults = this.getParamValue(params.Params, 'MaxResults') || 500;
// Execute the query
const response = await this.queryBC('generalLedgerEntries', filters, select, expand, orderBy, maxResults, contextUser);
const bcEntries = response.value || [];
const glEntries = [];
// Map entries and get account names
for (const entry of bcEntries) {
const mappedEntry = await this.mapBCEntryToGLEntry(entry, contextUser);
glEntries.push(mappedEntry);
}
// Calculate summary
const summary = this.calculateEntrySummary(glEntries);
// Create output parameters
if (!params.Params.find(p => p.Name === 'GLEntries')) {
params.Params.push({
Name: 'GLEntries',
Type: 'Output',
Value: glEntries
});
}
else {
params.Params.find(p => p.Name === 'GLEntries').Value = glEntries;
}
if (!params.Params.find(p => p.Name === 'TotalCount')) {
params.Params.push({
Name: 'TotalCount',
Type: 'Output',
Value: glEntries.length
});
}
else {
params.Params.find(p => p.Name === 'TotalCount').Value = glEntries.length;
}
if (!params.Params.find(p => p.Name === 'Summary')) {
params.Params.push({
Name: 'Summary',
Type: 'Output',
Value: summary
});
}
else {
params.Params.find(p => p.Name === 'Summary').Value = summary;
}
return {
Success: true,
ResultCode: 'SUCCESS',
Message: `Successfully retrieved ${glEntries.length} general ledger entries from Business Central`
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
return {
Success: false,
ResultCode: 'ERROR',
Message: errorMessage
};
}
}
/**
* Maps a Business Central GL entry to our standard interface
*/
async mapBCEntryToGLEntry(bcEntry, contextUser) {
// Get account name if not included
let accountName = bcEntry.accountName || '';
if (!accountName && bcEntry.accountId) {
try {
const accountResponse = await this.makeBCRequest(`generalLedgerAccounts(${bcEntry.accountId})`, 'GET', undefined, contextUser);
accountName = accountResponse.displayName || '';
}
catch (error) {
// If we can't get the account name, just use the number
accountName = bcEntry.accountNumber;
}
}
return {
id: bcEntry.id,
entryNumber: bcEntry.entryNumber,
postingDate: this.parseBCDate(bcEntry.postingDate),
documentNumber: bcEntry.documentNumber || '',
documentType: bcEntry.documentType || '',
accountId: bcEntry.accountId,
accountNumber: bcEntry.accountNumber,
accountName: accountName,
description: bcEntry.description || '',
debitAmount: bcEntry.debitAmount || 0,
creditAmount: bcEntry.creditAmount || 0,
amount: bcEntry.amount || 0,
lastModifiedDateTime: this.parseBCDate(bcEntry.lastModifiedDateTime),
dimensionSetLines: bcEntry.dimensionSetLines ? this.mapDimensionSetLines(bcEntry.dimensionSetLines) : undefined
};
}
/**
* Map dimension set lines
*/
mapDimensionSetLines(dimensions) {
return dimensions.map(dim => ({
id: dim.id,
code: dim.code,
displayName: dim.displayName || dim.code,
valueId: dim.valueId,
valueCode: dim.valueCode,
valueDisplayName: dim.valueDisplayName || dim.valueCode
}));
}
/**
* Calculate entry summary statistics
*/
calculateEntrySummary(entries) {
const summary = {
totalEntries: entries.length,
totalDebits: 0,
totalCredits: 0,
netAmount: 0,
earliestDate: null,
latestDate: null,
entriesByType: {},
entriesByAccount: {},
isBalanced: true
};
entries.forEach(entry => {
// Sum totals
summary.totalDebits += entry.debitAmount;
summary.totalCredits += entry.creditAmount;
summary.netAmount += entry.amount;
// Track dates
if (!summary.earliestDate || entry.postingDate < summary.earliestDate) {
summary.earliestDate = entry.postingDate;
}
if (!summary.latestDate || entry.postingDate > summary.latestDate) {
summary.latestDate = entry.postingDate;
}
// Count by type
const type = entry.documentType || 'Other';
summary.entriesByType[type] = (summary.entriesByType[type] || 0) + 1;
// Sum by account
const accountKey = `${entry.accountNumber} - ${entry.accountName}`;
if (!summary.entriesByAccount[accountKey]) {
summary.entriesByAccount[accountKey] = { count: 0, debit: 0, credit: 0 };
}
summary.entriesByAccount[accountKey].count++;
summary.entriesByAccount[accountKey].debit += entry.debitAmount;
summary.entriesByAccount[accountKey].credit += entry.creditAmount;
});
// Check if balanced (debits = credits)
summary.isBalanced = Math.abs(summary.totalDebits - summary.totalCredits) < 0.01;
return summary;
}
/**
* Define the parameters for this action
*/
get Params() {
const baseParams = this.getCommonAccountingParams();
const specificParams = [
{
Name: 'StartDate',
Type: 'Input',
Value: null
},
{
Name: 'EndDate',
Type: 'Input',
Value: null
},
{
Name: 'AccountNumber',
Type: 'Input',
Value: null
},
{
Name: 'DocumentNumber',
Type: 'Input',
Value: null
},
{
Name: 'DocumentType',
Type: 'Input',
Value: null
},
{
Name: 'MinAmount',
Type: 'Input',
Value: null
},
{
Name: 'MaxAmount',
Type: 'Input',
Value: null
},
{
Name: 'IncludeDimensions',
Type: 'Input',
Value: false
},
{
Name: 'MaxResults',
Type: 'Input',
Value: 500
}
];
return [...baseParams, ...specificParams];
}
};
exports.GetBusinessCentralGeneralLedgerEntriesAction = GetBusinessCentralGeneralLedgerEntriesAction;
exports.GetBusinessCentralGeneralLedgerEntriesAction = GetBusinessCentralGeneralLedgerEntriesAction = __decorate([
(0, global_1.RegisterClass)(actions_1.BaseAction, 'GetBusinessCentralGeneralLedgerEntriesAction')
], GetBusinessCentralGeneralLedgerEntriesAction);
//# sourceMappingURL=get-general-ledger-entries.action.js.map