UNPKG

@memberjunction/actions-bizapps-accounting

Version:

Accounting system integration actions for MemberJunction

257 lines 10.6 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.GetQuickBooksTransactionsAction = void 0; const global_1 = require("@memberjunction/global"); const quickbooks_base_action_1 = require("../quickbooks-base.action"); const actions_1 = require("@memberjunction/actions"); /** * Action to retrieve transactions from QuickBooks Online */ let GetQuickBooksTransactionsAction = class GetQuickBooksTransactionsAction extends quickbooks_base_action_1.QuickBooksBaseAction { /** * Description of the action */ get Description() { return 'Retrieves transactions from QuickBooks Online with flexible filtering options'; } /** * Main execution method */ async InternalRunAction(params) { try { const contextUser = params.ContextUser; if (!contextUser) { return { Success: false, ResultCode: 'ERROR_NO_CONTEXT_USER', Message: 'Context user is required for QuickBooks API calls', Params: params.Params }; } // Store params for use in other methods this._params = params.Params; const transactionType = this.getParamValue(params.Params, 'TransactionType'); const transactions = []; if (transactionType) { // Get specific transaction type const result = await this.getTransactionsByType(transactionType, params, contextUser); transactions.push(...result); } else { // Get all transaction types const types = ['Invoice', 'Bill', 'Payment', 'JournalEntry', 'Deposit', 'Purchase']; for (const type of types) { try { const result = await this.getTransactionsByType(type, params, contextUser); transactions.push(...result); } catch (error) { // Log but continue with other types console.warn(`Failed to retrieve ${type} transactions:`, error); } } } // Sort by date descending transactions.sort((a, b) => b.transactionDate.getTime() - a.transactionDate.getTime()); // Apply max results limit const maxResults = Math.min(this.getParamValue(params.Params, 'MaxResults') || 100, 1000); const limitedTransactions = transactions.slice(0, maxResults); // Create output parameters const outputParams = [ { Name: 'Transactions', Value: limitedTransactions, Type: 'Output' }, { Name: 'TotalCount', Value: limitedTransactions.length, Type: 'Output' }, { Name: 'HasMore', Value: transactions.length > maxResults, Type: 'Output' } ]; return { Success: true, ResultCode: 'SUCCESS', Message: `Successfully retrieved ${limitedTransactions.length} transactions`, Params: [...params.Params, ...outputParams] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { Success: false, ResultCode: 'ERROR', Message: errorMessage, Params: params.Params }; } } /** * Get transactions of a specific type */ async getTransactionsByType(type, params, contextUser) { // Build query for specific transaction type let query = `SELECT * FROM ${type}`; const conditions = []; // Add date range filter const startDate = this.getParamValue(params.Params, 'StartDate'); const endDate = this.getParamValue(params.Params, 'EndDate'); if (startDate) { conditions.push(`TxnDate >= '${this.formatQBODate(new Date(startDate))}'`); } if (endDate) { conditions.push(`TxnDate <= '${this.formatQBODate(new Date(endDate))}'`); } // Add amount filters const minAmount = this.getParamValue(params.Params, 'MinAmount'); const maxAmount = this.getParamValue(params.Params, 'MaxAmount'); if (minAmount !== undefined) { conditions.push(`TotalAmt >= ${minAmount}`); } if (maxAmount !== undefined) { conditions.push(`TotalAmt <= ${maxAmount}`); } // Add entity filter based on transaction type const entityId = this.getParamValue(params.Params, 'EntityID'); if (entityId) { if (['Invoice', 'Payment', 'Deposit'].includes(type)) { conditions.push(`CustomerRef = '${entityId}'`); } else if (['Bill', 'Purchase'].includes(type)) { conditions.push(`VendorRef = '${entityId}'`); } } // Add conditions to query if (conditions.length > 0) { query += ' WHERE ' + conditions.join(' AND '); } // Add ordering and limit query += ' ORDER BY TxnDate DESC'; query += ` MAXRESULTS ${this.getParamValue(params.Params, 'MaxResults') || 100}`; // Execute the query const response = await this.queryQBO(query, contextUser); const qbTransactions = response.QueryResponse?.[type] || []; return qbTransactions.map(qbTxn => this.mapQuickBooksTransaction(type, qbTxn)); } /** * Map QuickBooks transaction to standard format */ mapQuickBooksTransaction(type, qbTxn) { const transaction = { id: qbTxn.Id, transactionType: type, transactionNumber: qbTxn.DocNumber, transactionDate: this.parseQBODate(qbTxn.TxnDate), amount: qbTxn.TotalAmt || 0, currency: qbTxn.CurrencyRef?.value || 'USD', status: this.getTransactionStatus(type, qbTxn), referenceNumber: qbTxn.PrivateNote || qbTxn.CustomerMemo?.value, memo: qbTxn.Memo, entityName: this.getEntityName(type, qbTxn), entityId: this.getEntityId(type, qbTxn), lines: this.mapTransactionLines(type, qbTxn), metadata: qbTxn }; return transaction; } /** * Get transaction status based on type */ getTransactionStatus(type, qbTxn) { switch (type) { case 'Invoice': return qbTxn.Balance > 0 ? 'Unpaid' : 'Paid'; case 'Bill': return qbTxn.Balance > 0 ? 'Unpaid' : 'Paid'; case 'Payment': return 'Completed'; case 'JournalEntry': return 'Posted'; default: return qbTxn.TxnStatus || 'Unknown'; } } /** * Get entity name based on transaction type */ getEntityName(type, qbTxn) { if (['Invoice', 'Payment', 'Deposit'].includes(type)) { return qbTxn.CustomerRef?.name; } else if (['Bill', 'Purchase'].includes(type)) { return qbTxn.VendorRef?.name; } return undefined; } /** * Get entity ID based on transaction type */ getEntityId(type, qbTxn) { if (['Invoice', 'Payment', 'Deposit'].includes(type)) { return qbTxn.CustomerRef?.value; } else if (['Bill', 'Purchase'].includes(type)) { return qbTxn.VendorRef?.value; } return undefined; } /** * Map transaction lines */ mapTransactionLines(type, qbTxn) { const lines = []; const qbLines = qbTxn.Line || []; qbLines.forEach((line, index) => { // Skip summary lines if (line.DetailType === 'SubTotalLineDetail') { return; } const mappedLine = { id: line.Id || `${qbTxn.Id}-${index}`, lineNumber: index + 1, description: line.Description, amount: line.Amount || 0, accountId: this.getLineAccountId(line), accountName: this.getLineAccountName(line), itemId: line.SalesItemLineDetail?.ItemRef?.value || line.ItemBasedExpenseLineDetail?.ItemRef?.value, itemName: line.SalesItemLineDetail?.ItemRef?.name || line.ItemBasedExpenseLineDetail?.ItemRef?.name, quantity: line.SalesItemLineDetail?.Qty || line.ItemBasedExpenseLineDetail?.Qty, rate: line.SalesItemLineDetail?.UnitPrice || line.ItemBasedExpenseLineDetail?.UnitPrice }; lines.push(mappedLine); }); return lines; } /** * Get account ID from line detail */ getLineAccountId(line) { return line.AccountBasedExpenseLineDetail?.AccountRef?.value || line.DepositLineDetail?.AccountRef?.value || line.JournalEntryLineDetail?.AccountRef?.value; } /** * Get account name from line detail */ getLineAccountName(line) { return line.AccountBasedExpenseLineDetail?.AccountRef?.name || line.DepositLineDetail?.AccountRef?.name || line.JournalEntryLineDetail?.AccountRef?.name; } }; exports.GetQuickBooksTransactionsAction = GetQuickBooksTransactionsAction; exports.GetQuickBooksTransactionsAction = GetQuickBooksTransactionsAction = __decorate([ (0, global_1.RegisterClass)(actions_1.BaseAction, 'GetQuickBooksTransactionsAction') ], GetQuickBooksTransactionsAction); //# sourceMappingURL=get-transactions.action.js.map