Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model, Types } from 'mongoose'; import { GeneralLedgerEntry } from '../schemas/general-ledger-entry.schema'; import { LedgerAccount } from '../schemas/ledger-account.schema'; @Injectable() export class FinancialStatementService { constructor( @InjectModel(GeneralLedgerEntry.name) private readonly glModel: Model<GeneralLedgerEntry>, @InjectModel(LedgerAccount.name) private readonly accountModel: Model<LedgerAccount>, ) {} async getTrialBalance(tenantId: string, legalEntityId?: string): Promise<any[]> { const accounts = await this.accountModel.find({ tenantId }).exec(); const result = []; for (const acc of accounts) { // Aggregate GL entries for exact posted values const match: any = { tenantId: new Types.ObjectId(tenantId), ledgerAccountId: acc._id }; if (legalEntityId) match.legalEntityId = new Types.ObjectId(legalEntityId); const stats = await this.glModel.aggregate([ { $match: match }, { $group: { _id: null, totalDebit: { $sum: '$debitAmountMinor' }, totalCredit: { $sum: '$creditAmountMinor' } } } ]).exec(); const debits = stats[0]?.totalDebit || 0; const credits = stats[0]?.totalCredit || 0; result.push({ accountId: acc._id, accountCode: acc.accountCode, accountName: acc.accountName, accountType: acc.accountType, openingBalanceMinor: acc.openingBalanceMinor, debitTotalMinor: debits, creditTotalMinor: credits, closingBalanceMinor: acc.openingBalanceMinor + (acc.accountType === 'Asset' || acc.accountType === 'Expense' ? debits - credits : credits - debits) }); } return result; } async getProfitAndLoss(tenantId: string): Promise<{ revenue: any[]; expense: any[]; netProfitMinor: number }> { const accounts = await this.accountModel.find({ tenantId, accountType: { $in: ['Revenue', 'Expense'] } }).exec(); const revenue = []; const expense = []; let totalRevenue = 0; let totalExpense = 0; for (const acc of accounts) { const balance = acc.currentBalanceMinor; if (acc.accountType === 'Revenue') { totalRevenue += balance; revenue.push({ accountCode: acc.accountCode, accountName: acc.accountName, balanceMinor: balance }); } else { totalExpense += balance; expense.push({ accountCode: acc.accountCode, accountName: acc.accountName, balanceMinor: balance }); } } return { revenue, expense, netProfitMinor: totalRevenue - totalExpense }; } async getBalanceSheet(tenantId: string): Promise<{ assets: any[]; liabilities: any[]; equity: any[]; isBalanced: boolean }> { const accounts = await this.accountModel.find({ tenantId, accountType: { $in: ['Asset', 'Liability', 'Equity'] } }).exec(); const assets = []; const liabilities = []; const equity = []; let totalAssets = 0; let totalLiabEquity = 0; for (const acc of accounts) { const balance = acc.currentBalanceMinor; if (acc.accountType === 'Asset') { totalAssets += balance; assets.push({ accountCode: acc.accountCode, accountName: acc.accountName, balanceMinor: balance }); } else if (acc.accountType === 'Liability') { totalLiabEquity += balance; liabilities.push({ accountCode: acc.accountCode, accountName: acc.accountName, balanceMinor: balance }); } else { totalLiabEquity += balance; equity.push({ accountCode: acc.accountCode, accountName: acc.accountName, balanceMinor: balance }); } } return { assets, liabilities, equity, isBalanced: totalAssets === totalLiabEquity }; } } |