gemcap-be-common 1.2.140 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/classes/bank-transaction-item.d.ts +17 -0
- package/classes/bank-transaction-item.js +64 -0
- package/classes/bank-transaction-item.ts +66 -0
- package/classes/bank-uploaded-transaction.d.ts +17 -0
- package/classes/bank-uploaded-transaction.js +35 -0
- package/classes/bank-uploaded-transaction.ts +35 -0
- package/classes/inventory-item.d.ts +41 -0
- package/classes/inventory-item.js +44 -0
- package/classes/inventory-item.ts +63 -0
- package/classes/payable-account-item.d.ts +22 -0
- package/classes/payable-account-item.js +27 -0
- package/classes/payable-account-item.ts +35 -0
- package/classes/quickbook-item.d.ts +37 -0
- package/classes/quickbook-item.js +51 -0
- package/classes/quickbook-item.ts +59 -0
- package/classes/receivable-item.d.ts +26 -0
- package/classes/receivable-item.js +28 -0
- package/classes/receivable-item.ts +38 -0
- package/constants/date-formats.contsants.d.ts +1 -0
- package/constants/date-formats.contsants.js +4 -0
- package/constants/date-formats.contsants.ts +1 -0
- package/db/brokers.db.d.ts +185 -0
- package/db/brokers.db.js +35 -2
- package/db/brokers.db.ts +34 -1
- package/db/collateral-adjustments.db.d.ts +34 -0
- package/db/collateral-adjustments.db.js +52 -0
- package/db/collateral-adjustments.db.ts +54 -0
- package/db/collaterals.db.d.ts +1 -1
- package/db/equipment.db.d.ts +40 -0
- package/db/equipment.db.js +55 -0
- package/db/equipment.db.ts +56 -0
- package/db/financial-spreading.db.ts +2 -1
- package/db/groups.d.ts +5 -0
- package/db/groups.js +57 -0
- package/db/groups.ts +52 -0
- package/db/inventories.d.ts +91 -0
- package/db/inventories.js +449 -0
- package/db/inventories.ts +481 -0
- package/db/inventory-availability.d.ts +3 -0
- package/db/inventory-availability.js +103 -0
- package/db/inventory-availability.ts +113 -0
- package/db/new-summary.d.ts +31 -0
- package/db/new-summary.js +1295 -0
- package/db/new-summary.ts +1509 -0
- package/db/payable-accounts.d.ts +30 -0
- package/db/payable-accounts.js +55 -0
- package/db/payable-accounts.ts +50 -0
- package/db/reserve.db.d.ts +34 -0
- package/db/reserve.db.js +52 -0
- package/db/reserve.db.ts +48 -0
- package/db/uploads.db.d.ts +2 -0
- package/db/uploads.db.js +29 -0
- package/db/uploads.db.ts +24 -0
- package/helpers/main.helper.d.ts +31 -0
- package/helpers/main.helper.js +63 -0
- package/helpers/main.helper.ts +63 -0
- package/models/AccountPayableItem.model.d.ts +6 -6
- package/models/AllocatedBankTransaction.model.d.ts +54 -0
- package/models/AllocatedBankTransaction.model.js +70 -0
- package/models/AllocatedBankTransaction.model.ts +94 -0
- package/models/AllocatedData.model.d.ts +33 -0
- package/models/AllocatedData.model.js +19 -0
- package/models/AllocatedData.model.ts +24 -0
- package/models/BBCDate.model.d.ts +3 -3
- package/models/BBCSheet.model.d.ts +3 -3
- package/models/Banks.model.d.ts +3 -3
- package/models/Borrower.model.d.ts +3 -3
- package/models/BorrowerData.model.d.ts +3 -3
- package/models/BorrowerDataInsurance.model.d.ts +3 -3
- package/models/BorrowerDataTerm.model.d.ts +3 -3
- package/models/BorrowerSummary.model.js +1 -1
- package/models/BorrowerSummary.model.ts +1 -1
- package/models/CalandarDay.model.d.ts +40 -0
- package/models/CalandarDay.model.js +47 -0
- package/models/CalandarDay.model.ts +61 -0
- package/models/CashAllocationProduct.model.d.ts +119 -0
- package/models/CashAllocationProduct.model.js +102 -0
- package/models/CashAllocationProduct.model.ts +112 -0
- package/models/CashAllocationReference.model.d.ts +37 -0
- package/models/CashAllocationReference.model.js +27 -0
- package/models/CashAllocationReference.model.ts +40 -0
- package/models/CollateralAdjustment.model.d.ts +51 -0
- package/models/CollateralAdjustment.model.js +61 -0
- package/models/CollateralAdjustment.model.ts +98 -0
- package/models/Company.model.d.ts +35 -0
- package/models/Company.model.js +18 -0
- package/models/Company.model.ts +29 -0
- package/models/CustomerAPGroup.model.d.ts +32 -0
- package/models/CustomerAPGroup.model.js +24 -0
- package/models/CustomerAPGroup.model.ts +31 -0
- package/models/Equipment.model.d.ts +53 -0
- package/models/Equipment.model.js +140 -0
- package/models/Equipment.model.ts +172 -0
- package/models/FinancialCompliance.model.d.ts +39 -0
- package/models/FinancialCompliance.model.js +64 -0
- package/models/FinancialCompliance.model.ts +78 -0
- package/models/FinancialComplianceBorrower.model.d.ts +58 -0
- package/models/FinancialComplianceBorrower.model.js +82 -0
- package/models/FinancialComplianceBorrower.model.ts +118 -0
- package/models/FinancialIndexes.model.d.ts +36 -0
- package/models/FinancialIndexes.model.js +27 -0
- package/models/FinancialIndexes.model.ts +37 -0
- package/models/Inventory.model.d.ts +18 -18
- package/models/InventoryAvailability.model.d.ts +21 -21
- package/models/InventoryAvailabilityItem.model.d.ts +6 -6
- package/models/InventoryItem.model.d.ts +24 -24
- package/models/InventoryManualEntry.model.d.ts +9 -9
- package/models/InventorySeasonalRates.model.d.ts +3 -3
- package/models/LoanBroker.model.d.ts +3 -3
- package/models/LoanCharges.model.d.ts +12 -12
- package/models/LoanProducts.model.d.ts +9 -9
- package/models/LoanStatementStatus.model.d.ts +35 -0
- package/models/LoanStatementStatus.model.js +34 -0
- package/models/LoanStatementStatus.model.ts +45 -0
- package/models/LoanStatementTransaction.model.d.ts +9 -9
- package/models/LoanTransactionFile.model.d.ts +41 -0
- package/models/LoanTransactionFile.model.js +44 -0
- package/models/LoanTransactionFile.model.ts +61 -0
- package/models/MappedGroup.model.d.ts +37 -0
- package/models/MappedGroup.model.js +33 -0
- package/models/MappedGroup.model.ts +46 -0
- package/models/MonthEndData.Model.d.ts +41 -0
- package/models/MonthEndData.Model.js +42 -0
- package/models/MonthEndData.Model.ts +53 -0
- package/models/OrganizationEmails.model.d.ts +44 -0
- package/models/OrganizationEmails.model.js +40 -0
- package/models/OrganizationEmails.model.ts +54 -0
- package/models/ProductBroker.model.d.ts +9 -9
- package/models/QuickbooksAccount.model.d.ts +39 -0
- package/models/QuickbooksAccount.model.js +43 -0
- package/models/QuickbooksAccount.model.ts +57 -0
- package/models/Receivable.model.d.ts +12 -12
- package/models/ReceivableAvailability.model.d.ts +54 -54
- package/models/ReceivableAvailabilityItem.model.d.ts +57 -57
- package/models/ReceivableItem.model.d.ts +6 -6
- package/models/Reserve.model.d.ts +51 -0
- package/models/Reserve.model.js +96 -0
- package/models/Reserve.model.ts +125 -0
- package/models/TermLoan.model.d.ts +3 -3
- package/models/TermLoanCalculated.model.d.ts +6 -6
- package/models/TransactionAttachedFile.Model.d.ts +35 -0
- package/models/TransactionAttachedFile.Model.js +37 -0
- package/models/TransactionAttachedFile.Model.ts +48 -0
- package/models/UploadedBankTransaction.model.d.ts +56 -0
- package/models/UploadedBankTransaction.model.js +78 -0
- package/models/UploadedBankTransaction.model.ts +110 -0
- package/models/UploadedData.model.d.ts +36 -0
- package/models/UploadedData.model.js +23 -0
- package/models/UploadedData.model.ts +35 -0
- package/models/UploadedFile.model.d.ts +40 -0
- package/models/UploadedFile.model.js +41 -0
- package/models/UploadedFile.model.ts +57 -0
- package/models/UploadedSheet.model.d.ts +46 -0
- package/models/UploadedSheet.model.js +27 -0
- package/models/UploadedSheet.model.ts +51 -0
- package/package.json +10 -1
- package/repositories/globals.repository.d.ts +8 -0
- package/repositories/globals.repository.js +24 -0
- package/repositories/globals.repository.ts +21 -0
- package/services/attached-files.service.d.ts +57 -0
- package/services/attached-files.service.js +103 -0
- package/services/attached-files.service.ts +123 -0
- package/services/availability.service.d.ts +77 -0
- package/services/availability.service.js +897 -0
- package/services/availability.service.ts +1034 -0
- package/services/bank-uploaded-transactions.service.d.ts +33 -0
- package/services/bank-uploaded-transactions.service.js +430 -0
- package/services/bank-uploaded-transactions.service.ts +475 -0
- package/services/banks.service.d.ts +36 -0
- package/services/banks.service.js +91 -0
- package/services/banks.service.ts +95 -0
- package/services/borrower-summary.service.d.ts +35 -0
- package/services/borrower-summary.service.js +310 -0
- package/services/borrower-summary.service.ts +334 -0
- package/services/borrowers.service.d.ts +103 -0
- package/services/borrowers.service.js +268 -0
- package/services/borrowers.service.ts +302 -0
- package/services/brokers.service.d.ts +212 -0
- package/services/brokers.service.js +160 -0
- package/services/brokers.service.ts +200 -0
- package/services/calendar.service.d.ts +53 -0
- package/services/calendar.service.js +108 -0
- package/services/calendar.service.ts +128 -0
- package/services/cash-allocation.service.d.ts +40 -0
- package/services/cash-allocation.service.js +92 -0
- package/services/cash-allocation.service.ts +105 -0
- package/services/collateral-adjustments.service.d.ts +38 -0
- package/services/collateral-adjustments.service.js +82 -0
- package/services/collateral-adjustments.service.ts +95 -0
- package/services/collaterals.service.d.ts +69 -0
- package/services/collaterals.service.js +279 -0
- package/services/collaterals.service.ts +319 -0
- package/services/companies.service.d.ts +5 -0
- package/services/companies.service.js +21 -0
- package/services/companies.service.ts +23 -0
- package/services/compliance-borrowers.service.d.ts +152 -0
- package/services/compliance-borrowers.service.js +569 -0
- package/services/compliance-borrowers.service.ts +617 -0
- package/services/equipment.service.d.ts +42 -0
- package/services/equipment.service.js +120 -0
- package/services/equipment.service.ts +149 -0
- package/services/file-manager.service.d.ts +44 -0
- package/services/file-manager.service.js +120 -0
- package/services/file-manager.service.ts +146 -0
- package/services/financial-compliance.service.d.ts +58 -0
- package/services/financial-compliance.service.js +281 -0
- package/services/financial-compliance.service.ts +309 -0
- package/services/financial-indexes.service.d.ts +20 -0
- package/services/financial-indexes.service.js +241 -0
- package/services/financial-indexes.service.ts +257 -0
- package/services/financial-spreading.service.d.ts +74 -0
- package/services/financial-spreading.service.js +450 -0
- package/services/financial-spreading.service.ts +517 -0
- package/services/globals.service.d.ts +5 -0
- package/services/globals.service.js +11 -0
- package/services/globals.service.ts +8 -0
- package/services/groups.service.d.ts +39 -0
- package/services/groups.service.js +65 -0
- package/services/groups.service.ts +64 -0
- package/services/inventory-availability.service.d.ts +13 -0
- package/services/inventory-availability.service.js +170 -0
- package/services/inventory-availability.service.ts +187 -0
- package/services/inventory.service.d.ts +118 -0
- package/services/inventory.service.js +239 -0
- package/services/inventory.service.ts +276 -0
- package/services/loan-charges.service.d.ts +83 -0
- package/services/loan-charges.service.js +343 -0
- package/services/loan-charges.service.ts +396 -0
- package/services/loan-payments.service.d.ts +94 -0
- package/services/loan-payments.service.js +485 -0
- package/services/loan-payments.service.ts +541 -0
- package/services/loan-products.service.d.ts +12 -0
- package/services/loan-products.service.js +55 -0
- package/services/loan-products.service.ts +58 -0
- package/services/loan-statement-balance.service.d.ts +16 -0
- package/services/loan-statement-balance.service.js +106 -0
- package/services/loan-statement-balance.service.ts +113 -0
- package/services/loan-statement-effects.service.d.ts +8 -0
- package/services/loan-statement-effects.service.js +42 -0
- package/services/loan-statement-effects.service.ts +41 -0
- package/services/loan-statement-status.service.d.ts +208 -0
- package/services/loan-statement-status.service.js +159 -0
- package/services/loan-statement-status.service.ts +177 -0
- package/services/loan-statement.service.d.ts +186 -0
- package/services/loan-statement.service.js +935 -0
- package/services/loan-statement.service.ts +1040 -0
- package/services/loan-transactions.service.d.ts +169 -0
- package/services/loan-transactions.service.js +941 -0
- package/services/loan-transactions.service.ts +1042 -0
- package/services/lock.service.d.ts +6 -0
- package/services/lock.service.js +45 -0
- package/services/lock.service.ts +45 -0
- package/services/manual-entry.service.d.ts +20 -0
- package/services/manual-entry.service.js +186 -0
- package/services/manual-entry.service.ts +201 -0
- package/services/month-end-data.service.d.ts +34 -0
- package/services/month-end-data.service.js +30 -0
- package/services/month-end-data.service.ts +35 -0
- package/services/nodemailer.service.d.ts +96 -0
- package/services/nodemailer.service.js +689 -0
- package/services/nodemailer.service.ts +774 -0
- package/services/organization-emails.service.d.ts +31 -0
- package/services/organization-emails.service.js +10 -0
- package/services/organization-emails.service.ts +7 -0
- package/services/organizations.service.d.ts +34 -0
- package/services/organizations.service.js +74 -0
- package/services/organizations.service.ts +84 -0
- package/services/pdf.service.d.ts +61 -0
- package/services/pdf.service.js +547 -0
- package/services/pdf.service.ts +642 -0
- package/services/quickbooks.service.d.ts +99 -0
- package/services/quickbooks.service.js +640 -0
- package/services/quickbooks.service.ts +734 -0
- package/services/reports/investor-summary.service.d.ts +28 -0
- package/services/reports/investor-summary.service.js +136 -0
- package/services/reports/investor-summary.service.ts +159 -0
- package/services/reports.service.d.ts +126 -0
- package/services/reports.service.js +584 -0
- package/services/reports.service.ts +702 -0
- package/services/reserve.service.d.ts +37 -0
- package/services/reserve.service.js +76 -0
- package/services/reserve.service.ts +79 -0
- package/services/sentry.service.d.ts +11 -0
- package/services/sentry.service.js +49 -0
- package/services/sentry.service.ts +33 -0
- package/services/signs.service.d.ts +69 -0
- package/services/signs.service.js +230 -0
- package/services/signs.service.ts +260 -0
- package/services/term-loan.service.d.ts +30 -0
- package/services/term-loan.service.js +614 -0
- package/services/term-loan.service.ts +696 -0
- package/services/uploads.service.d.ts +134 -0
- package/services/uploads.service.js +587 -0
- package/services/uploads.service.ts +643 -0
- package/services/user-logs.service.d.ts +23 -0
- package/services/user-logs.service.js +160 -0
- package/services/user-logs.service.ts +177 -0
- package/services/users.service.d.ts +4 -4
- package/services/yield.service.d.ts +46 -0
- package/services/yield.service.js +42 -12
- package/services/yield.service.ts +38 -8
- package/tsconfig.json +5 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import Decimal from 'decimal.js';
|
|
3
|
+
|
|
4
|
+
import { BorrowerModel } from '../models/Borrower.model';
|
|
5
|
+
import { defaultDateFormat, formatDate } from '../helpers/date.helper';
|
|
6
|
+
import { IInventoryAvailabilitySummary } from '../models/InventoryAvailability.model';
|
|
7
|
+
import { IReserveSummary, IReserveSummaryItem } from '../models/Reserve.model';
|
|
8
|
+
import { IAvailabilitySummary } from '../models/ReceivableAvailability.model';
|
|
9
|
+
import { IEquipmentSummary } from '../models/Equipment.model';
|
|
10
|
+
import { ELoanTypes } from '../enums/loan-types.enum';
|
|
11
|
+
import { EReserveTypes } from '../enums/reserve-types.enum';
|
|
12
|
+
import { EEquipmentTypes } from '../enums/equipment-types.enum';
|
|
13
|
+
import { ELedgerReportType } from '../db/loan-statement.db';
|
|
14
|
+
import { getLedger, ReportLedgerOptions, ReportLedgerParams } from '../db/reports.db';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
IInvestorSummaryDataRow,
|
|
18
|
+
InvestorSummaryService,
|
|
19
|
+
} from './reports/investor-summary.service';
|
|
20
|
+
import { defaultPDFPageMarginSize } from './pdf.service';
|
|
21
|
+
import { AvailabilityService } from './availability.service';
|
|
22
|
+
import { BorrowerService } from './borrowers.service';
|
|
23
|
+
import { CollateralAdjustmentsService } from './collateral-adjustments.service';
|
|
24
|
+
import { CollateralsService } from './collaterals.service';
|
|
25
|
+
import { EquipmentService } from './equipment.service';
|
|
26
|
+
import { LoanChargesService } from './loan-charges.service';
|
|
27
|
+
import { LoanTransactionsService } from './loan-transactions.service';
|
|
28
|
+
import { SignsService } from './signs.service';
|
|
29
|
+
import { UploadsService } from './uploads.service';
|
|
30
|
+
|
|
31
|
+
export interface IBankReportData {
|
|
32
|
+
borrowerId?: string;
|
|
33
|
+
borrowerName: string;
|
|
34
|
+
productCode: string;
|
|
35
|
+
productType: string;
|
|
36
|
+
commitment: number;
|
|
37
|
+
startDate: Date;
|
|
38
|
+
maturityDate: Date;
|
|
39
|
+
inventoryGrossValue: number;
|
|
40
|
+
inventoryAdvanceRate: number;
|
|
41
|
+
inventoryReserves: number;
|
|
42
|
+
inventoryNet: number;
|
|
43
|
+
ARGross: number;
|
|
44
|
+
ARAdvanceRate: number;
|
|
45
|
+
ARReserves: number;
|
|
46
|
+
ARNet: number;
|
|
47
|
+
otherReserves: number;
|
|
48
|
+
collateralAdjustments: number;
|
|
49
|
+
totalCollateral: number;
|
|
50
|
+
loanBalanceRevolver: number;
|
|
51
|
+
netRevolverAvailability: number;
|
|
52
|
+
equipmentCollateral: number;
|
|
53
|
+
intellectualProperty: number;
|
|
54
|
+
realEstate: number;
|
|
55
|
+
bootCollateral: number;
|
|
56
|
+
termLoanReserves: number;
|
|
57
|
+
loanTermBalance: number;
|
|
58
|
+
netTermAvailability: number;
|
|
59
|
+
participantBalance: number;
|
|
60
|
+
NAISC: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface IReportDataItem {
|
|
64
|
+
name: string;
|
|
65
|
+
grossValue: number;
|
|
66
|
+
advanceRate: number;
|
|
67
|
+
netValue: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface ISummaryReportDataGroup {
|
|
71
|
+
NAISCCode: string;
|
|
72
|
+
isExternalAppraisal: boolean;
|
|
73
|
+
isCompliant: boolean;
|
|
74
|
+
productCode: string;
|
|
75
|
+
items: IReportDataItem[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface ISummaryReportData {
|
|
79
|
+
borrowerName: string;
|
|
80
|
+
bbcDate: Date;
|
|
81
|
+
revolverDataGroup: ISummaryReportDataGroup;
|
|
82
|
+
termDataGroup: ISummaryReportDataGroup;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const createReportItemFromInventory = (item: IInventoryAvailabilitySummary): IReportDataItem => {
|
|
86
|
+
return {
|
|
87
|
+
name: item.inventoryName,
|
|
88
|
+
grossValue: -item.totalValue,
|
|
89
|
+
advanceRate: item.advanceRate * 100,
|
|
90
|
+
netValue: -item.availability,
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const createReportItemFromEquipment = (items: IEquipmentSummary): IReportDataItem[] => {
|
|
95
|
+
const titleMap = {
|
|
96
|
+
EQUIPMENT: 'Equipment',
|
|
97
|
+
INTELLECTUAL_PROPERTY: 'Intellectual property',
|
|
98
|
+
REAL_ESTATE: 'Real estate',
|
|
99
|
+
BOOT_COLLATERAL: 'Boot collateral',
|
|
100
|
+
};
|
|
101
|
+
return Object.entries(titleMap).map(([key, title]) => {
|
|
102
|
+
return <IReportDataItem>{
|
|
103
|
+
name: title,
|
|
104
|
+
grossValue: items[key].amount,
|
|
105
|
+
advanceRate: items[key].advanceRate,
|
|
106
|
+
netValue: items[key].availability,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const createReportItemFromReserve = (item: IReserveSummaryItem, reserveName: string): IReportDataItem => {
|
|
112
|
+
return {
|
|
113
|
+
name: reserveName,
|
|
114
|
+
grossValue: 0,
|
|
115
|
+
advanceRate: 0,
|
|
116
|
+
netValue: -item.amount,
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const createReportItemsFromReceivable = (receivable: IAvailabilitySummary): {
|
|
121
|
+
arUninsured: IReportDataItem,
|
|
122
|
+
arInsured: IReportDataItem
|
|
123
|
+
} => {
|
|
124
|
+
const getArUninsured = () => {
|
|
125
|
+
return receivable
|
|
126
|
+
? {
|
|
127
|
+
grossValue: receivable.uninsuredComponent,
|
|
128
|
+
advanceRate: receivable.uninsuredComponent === 0 ? 0 : new Decimal(receivable.uninsuredAvailability).div(receivable.uninsuredComponent).mul(100).toDP(2).toNumber(),
|
|
129
|
+
netValue: receivable.uninsuredAvailability,
|
|
130
|
+
}
|
|
131
|
+
: {
|
|
132
|
+
grossValue: 0,
|
|
133
|
+
advanceRate: 0,
|
|
134
|
+
netValue: 0,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
const getArInsured = () => {
|
|
138
|
+
return receivable
|
|
139
|
+
? {
|
|
140
|
+
grossValue: receivable.insuredComponent,
|
|
141
|
+
advanceRate: receivable.insuredComponent === 0 ? 0 : new Decimal(receivable.insuredAvailability).div(receivable.insuredComponent).mul(100).toDP(2).toNumber(),
|
|
142
|
+
netValue: receivable.insuredAvailability,
|
|
143
|
+
}
|
|
144
|
+
: {
|
|
145
|
+
grossValue: 0,
|
|
146
|
+
advanceRate: 0,
|
|
147
|
+
netValue: 0,
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
return {
|
|
151
|
+
arUninsured: {
|
|
152
|
+
name: 'AR Uninsured',
|
|
153
|
+
...getArUninsured(),
|
|
154
|
+
},
|
|
155
|
+
arInsured: {
|
|
156
|
+
name: 'AR Insured',
|
|
157
|
+
...getArInsured(),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const createTotalRows = (allResults: IReportDataItem[], productType: 'TERM' | 'REVOLVER', loanBalance: number) => {
|
|
163
|
+
const productTypeTitles = {
|
|
164
|
+
REVOLVER: {
|
|
165
|
+
totalCollateral: 'TOTAL REVOLVING COLLATERAL',
|
|
166
|
+
loanBalance: 'LOAN BALANCE (Revolving products only)',
|
|
167
|
+
netAvailability: 'NET REVOLVER AVAILABILITY',
|
|
168
|
+
},
|
|
169
|
+
TERM: {
|
|
170
|
+
totalCollateral: 'TOTAL TERM COLLATERAL',
|
|
171
|
+
loanBalance: 'LOAN BALANCE (Term products only)',
|
|
172
|
+
netAvailability: 'NET TERM AVAILABILITY',
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
const totalCollateralRow = allResults.reduce((acc, item) => {
|
|
176
|
+
acc.grossValue = new Decimal(acc.grossValue).plus(item.grossValue).toNumber();
|
|
177
|
+
acc.netValue = new Decimal(acc.netValue).plus(item.netValue).toNumber();
|
|
178
|
+
acc.advanceRate = item.grossValue === 0 ? 0 : new Decimal(acc.netValue).div(item.grossValue).toDP(2).toNumber();
|
|
179
|
+
return acc;
|
|
180
|
+
}, <IReportDataItem>{
|
|
181
|
+
name: productTypeTitles[productType].totalCollateral,
|
|
182
|
+
grossValue: 0,
|
|
183
|
+
advanceRate: 0,
|
|
184
|
+
netValue: 0,
|
|
185
|
+
});
|
|
186
|
+
const loanBalanceRow: IReportDataItem = {
|
|
187
|
+
name: productTypeTitles[productType].loanBalance,
|
|
188
|
+
grossValue: loanBalance,
|
|
189
|
+
advanceRate: 0,
|
|
190
|
+
netValue: loanBalance,
|
|
191
|
+
};
|
|
192
|
+
const netAvailabilityRow: IReportDataItem = {
|
|
193
|
+
name: productTypeTitles[productType].netAvailability,
|
|
194
|
+
grossValue: 0,
|
|
195
|
+
advanceRate: 0,
|
|
196
|
+
netValue: new Decimal(totalCollateralRow.netValue).sub(loanBalanceRow.netValue).toNumber(),
|
|
197
|
+
};
|
|
198
|
+
return { totalCollateralRow, loanBalanceRow, netAvailabilityRow };
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const getInventoryGrossValue = (inventory: IInventoryAvailabilitySummary[]) => {
|
|
202
|
+
const foundInv = inventory?.find((s) => s.inventoryName === 'TOTAL');
|
|
203
|
+
if (foundInv) {
|
|
204
|
+
return foundInv.totalValue;
|
|
205
|
+
}
|
|
206
|
+
return 0;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const getInventoryAdvanceRate = (inventory: IInventoryAvailabilitySummary[]) => {
|
|
210
|
+
const foundInv = inventory?.find((s) => s.inventoryName === 'TOTAL');
|
|
211
|
+
if (foundInv) {
|
|
212
|
+
return foundInv.availability;
|
|
213
|
+
}
|
|
214
|
+
return 0;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const getInventoryReservesValue = (reserve: IReserveSummary) => {
|
|
218
|
+
return reserve[EReserveTypes.INVENTORY]?.amount ?? 0;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const getARGross = (receivable: IAvailabilitySummary) => {
|
|
222
|
+
return !receivable ? 0 : new Decimal(receivable.uninsuredComponent || 0).add(receivable.insuredComponent || 0).toNumber();
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const getARAdvanceRate = (receivable: IAvailabilitySummary) => {
|
|
226
|
+
return !receivable ? 0 : new Decimal(receivable.uninsuredAvailability || 0).add(receivable.insuredAvailability || 0).toNumber();
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const getOtherValue = (reserves: IReserveSummary) => {
|
|
230
|
+
return Object
|
|
231
|
+
.entries(reserves)
|
|
232
|
+
.reduce((acc, [key, el]) => {
|
|
233
|
+
if (key === EReserveTypes.EQUIPMENT ||
|
|
234
|
+
key === EReserveTypes.INVENTORY ||
|
|
235
|
+
key === EReserveTypes.RECEIVABLES) {
|
|
236
|
+
return acc;
|
|
237
|
+
}
|
|
238
|
+
return new Decimal(acc || 0).sub(el.amount).toNumber();
|
|
239
|
+
}, 0);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
export class ReportsService {
|
|
245
|
+
|
|
246
|
+
margin = defaultPDFPageMarginSize;
|
|
247
|
+
|
|
248
|
+
constructor(
|
|
249
|
+
private readonly availabilityService: AvailabilityService,
|
|
250
|
+
private readonly borrowerService: BorrowerService,
|
|
251
|
+
private readonly collateralAdjustmentsService: CollateralAdjustmentsService,
|
|
252
|
+
private readonly collateralsService: CollateralsService,
|
|
253
|
+
private readonly equipmentService: EquipmentService,
|
|
254
|
+
private readonly loanChargesService: LoanChargesService,
|
|
255
|
+
private readonly loanTransactionsService: LoanTransactionsService,
|
|
256
|
+
private readonly signsService: SignsService,
|
|
257
|
+
private readonly uploadsService: UploadsService,
|
|
258
|
+
private readonly investorSummaryService: InvestorSummaryService,
|
|
259
|
+
) {
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async getCollateralAdjustmentsForLastSignedBBC(borrowerId: string, date: Date) {
|
|
263
|
+
const lastSignedBBC = await this.signsService.getLatestSignedBBCDate(borrowerId, date);
|
|
264
|
+
if (!lastSignedBBC) {
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
const summary = await this.collateralAdjustmentsService.getCollateralAdjustmentSummary(lastSignedBBC._id.toString());
|
|
268
|
+
return Object.values(summary).reduce((acc, summaryRow) => (new Decimal(acc).add(summaryRow.amount).toNumber()), 0);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
private async getProductBalances(productId: string, isRevolver: boolean, date: Date) {
|
|
272
|
+
const lastTransaction = await this.loanTransactionsService.getLastTransactionForDate(productId, date);
|
|
273
|
+
const balance = lastTransaction ? lastTransaction.balance : 0;
|
|
274
|
+
const availability = -balance;
|
|
275
|
+
const balances: Partial<IBankReportData> = {
|
|
276
|
+
loanBalanceRevolver: isRevolver ? balance : 0,
|
|
277
|
+
netRevolverAvailability: isRevolver ? availability : 0,
|
|
278
|
+
loanTermBalance: isRevolver ? 0 : balance,
|
|
279
|
+
netTermAvailability: isRevolver ? 0 : availability,
|
|
280
|
+
};
|
|
281
|
+
return balances;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
public async getBorrowerAndProducts(borrowerId: string, date: Date, useSignedBBC = false, requireBBC = true) {
|
|
285
|
+
const borrower = await BorrowerModel.findById(borrowerId);
|
|
286
|
+
if (!borrower) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const latestBBC = useSignedBBC
|
|
291
|
+
? await this.signsService.getLatestSignedBBCDate(borrowerId, date)
|
|
292
|
+
: await this.collateralsService.getLatestBBC(borrowerId, date);
|
|
293
|
+
if (!latestBBC && requireBBC) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const summaries = latestBBC ? await this.availabilityService.getAllSummaries(latestBBC._id.toString(), null) : null;
|
|
298
|
+
|
|
299
|
+
const products = await this.loanChargesService.getLoanProducts(borrowerId);
|
|
300
|
+
return { borrower, latestBBC, summaries, products };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
public async generatePortfolioSummary(borrowerIds: string[], date: Date) {
|
|
304
|
+
if (borrowerIds.length === 0) {
|
|
305
|
+
return {};
|
|
306
|
+
}
|
|
307
|
+
const allResults: { [borrowerId: string]: ISummaryReportData } = {};
|
|
308
|
+
await Promise.all(borrowerIds.map(async (borrowerId) => {
|
|
309
|
+
const borrowerData = await this.getBorrowerAndProducts(borrowerId, date, true);
|
|
310
|
+
if (!borrowerData) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const { borrower, latestBBC, summaries, products } = borrowerData;
|
|
314
|
+
if (!borrower) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const revolverProduct = products.find((product) => product.type === ELoanTypes.REVOLVER);
|
|
318
|
+
const termProduct = products.find((product) => product.type === ELoanTypes.TERM);
|
|
319
|
+
|
|
320
|
+
let revolverDataGroup: ISummaryReportDataGroup = null;
|
|
321
|
+
|
|
322
|
+
if (revolverProduct) {
|
|
323
|
+
const inventoryItems = summaries.inventory.map(createReportItemFromInventory);
|
|
324
|
+
const inventoryReserve = createReportItemFromReserve(summaries.reserve['INVENTORY'], 'Inventory Reserves');
|
|
325
|
+
const ARReserve = createReportItemFromReserve(summaries.reserve['RECEIVABLES'], 'AR Reserves');
|
|
326
|
+
const otherReserve = createReportItemFromReserve(summaries.reserve['OTHER'], 'Other non-equipment reserves');
|
|
327
|
+
const { arUninsured, arInsured } = createReportItemsFromReceivable(summaries.receivable);
|
|
328
|
+
const revolverItems = [...inventoryItems, inventoryReserve, arUninsured, arInsured, ARReserve, otherReserve];
|
|
329
|
+
const revolverBalance = await this.loanChargesService.getLoanProductBalance(revolverProduct._id.toString(), date);
|
|
330
|
+
const {
|
|
331
|
+
totalCollateralRow: totalCollateralRowRevolver,
|
|
332
|
+
loanBalanceRow: loanBalanceRowRevolver,
|
|
333
|
+
netAvailabilityRow: netAvailabilityRowRevolver,
|
|
334
|
+
} = createTotalRows(revolverItems, 'REVOLVER', revolverBalance.balance);
|
|
335
|
+
revolverDataGroup = {
|
|
336
|
+
NAISCCode: '',
|
|
337
|
+
productCode: '',
|
|
338
|
+
isCompliant: false,
|
|
339
|
+
isExternalAppraisal: false,
|
|
340
|
+
items: [...revolverItems, totalCollateralRowRevolver, loanBalanceRowRevolver, netAvailabilityRowRevolver],
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
let termDataGroup: ISummaryReportDataGroup = null;
|
|
345
|
+
if (termProduct) {
|
|
346
|
+
const equipmentItems = createReportItemFromEquipment(summaries.equipment);
|
|
347
|
+
const termReserve = createReportItemFromReserve(summaries.reserve['EQUIPMENT'], 'Term Loan Reserves (total)');
|
|
348
|
+
const termItems = [...equipmentItems, termReserve];
|
|
349
|
+
const termBalance = await this.loanChargesService.getLoanProductBalance(termProduct._id.toString(), date);
|
|
350
|
+
const {
|
|
351
|
+
totalCollateralRow: totalCollateralRowTerm,
|
|
352
|
+
loanBalanceRow: loanBalanceRowTerm,
|
|
353
|
+
netAvailabilityRow: netAvailabilityRowTerm,
|
|
354
|
+
} = createTotalRows(termItems, 'TERM', termBalance.balance);
|
|
355
|
+
termDataGroup = {
|
|
356
|
+
NAISCCode: '',
|
|
357
|
+
productCode: '',
|
|
358
|
+
isCompliant: false,
|
|
359
|
+
isExternalAppraisal: false,
|
|
360
|
+
items: [...termItems, totalCollateralRowTerm, loanBalanceRowTerm, netAvailabilityRowTerm],
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
allResults[borrowerId] = {
|
|
364
|
+
borrowerName: borrower.name,
|
|
365
|
+
bbcDate: latestBBC.bbcDate,
|
|
366
|
+
revolverDataGroup,
|
|
367
|
+
termDataGroup,
|
|
368
|
+
};
|
|
369
|
+
}));
|
|
370
|
+
return allResults;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
public async getPortfolioSummaryExcel(borrowerIds: string[], date: Date) {
|
|
374
|
+
const report = await this.generatePortfolioSummary(borrowerIds, date);
|
|
375
|
+
const emptyRow = [['']];
|
|
376
|
+
const reportHeader = [
|
|
377
|
+
['PORTFOLIO LOAN BALANCE AND COLLATERAL REPORT'],
|
|
378
|
+
[`RUN DATE ${formatDate(date)}`],
|
|
379
|
+
[''],
|
|
380
|
+
];
|
|
381
|
+
const reportToCovert = Object.values(report).reduce((acc, borrowerData) => {
|
|
382
|
+
const headers = [
|
|
383
|
+
[`LOAN BALANCE AND COLLATERAL REPORT ${borrowerData.borrowerName}, Last BBC date - ${formatDate(borrowerData.bbcDate)}`],
|
|
384
|
+
['', 'Gross Value', 'Advance Rate', 'Net Value'],
|
|
385
|
+
];
|
|
386
|
+
const convertToExcel = (dataGroup: ISummaryReportDataGroup) => {
|
|
387
|
+
if (!dataGroup) {
|
|
388
|
+
return [];
|
|
389
|
+
}
|
|
390
|
+
return dataGroup.items.reduce((acc, revolverItem: IReportDataItem) => {
|
|
391
|
+
if (revolverItem.name === 'TOTAL') {
|
|
392
|
+
return acc;
|
|
393
|
+
}
|
|
394
|
+
return [...acc, [...Object.values(revolverItem).map((v) => v === 0 ? '-' : v)]];
|
|
395
|
+
}, []);
|
|
396
|
+
};
|
|
397
|
+
const revolverData = convertToExcel(borrowerData.revolverDataGroup);
|
|
398
|
+
const termData = convertToExcel(borrowerData.termDataGroup);
|
|
399
|
+
return [...acc, ...headers, ...revolverData, ...emptyRow, ...termData, ...emptyRow, ...emptyRow];
|
|
400
|
+
}, [...reportHeader]);
|
|
401
|
+
return await this.uploadsService.convertDataToFile([{ portfolio: reportToCovert }]);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
public async generateBankPortfolioSummary(borrowerIds: string[], date: Date, {
|
|
405
|
+
useSignedBBC,
|
|
406
|
+
useStoredBalance,
|
|
407
|
+
} = { useSignedBBC: true, useStoredBalance: false }) {
|
|
408
|
+
const productsGrouped = await Promise.all(borrowerIds.map(async (borrowerId) => {
|
|
409
|
+
const borrowerData = await this.getBorrowerAndProducts(borrowerId, date, useSignedBBC, false);
|
|
410
|
+
if (!borrowerData) {
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const { borrower, summaries, products } = borrowerData;
|
|
415
|
+
if (!borrower) {
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const borrowerSettings = await this.borrowerService.getBorrowerSettings(borrowerId);
|
|
420
|
+
const borrowerOptions = borrowerSettings.data.options;
|
|
421
|
+
const NAISCCodeOption = borrowerOptions.find((option) => option['dataName'] === 'NAISC Code');
|
|
422
|
+
const NAISCCode = NAISCCodeOption ? NAISCCodeOption.dataValue as string : '';
|
|
423
|
+
|
|
424
|
+
const hasTermProduct = products.some((product) => product.type === ELoanTypes.TERM);
|
|
425
|
+
const manyTermProduct = products.filter((product) => product.type === ELoanTypes.TERM).length > 1;
|
|
426
|
+
|
|
427
|
+
return await Promise.all(products.map(async (product) => {
|
|
428
|
+
if (product.isParticipant) {
|
|
429
|
+
return null as IBankReportData;
|
|
430
|
+
}
|
|
431
|
+
const isRevolver = product.type === ELoanTypes.REVOLVER;
|
|
432
|
+
const productMainData: Partial<IBankReportData> = {
|
|
433
|
+
borrowerId,
|
|
434
|
+
borrowerName: borrower.name,
|
|
435
|
+
productCode: product.code,
|
|
436
|
+
productType: product.type,
|
|
437
|
+
commitment: product.commitment,
|
|
438
|
+
startDate: product.startDate,
|
|
439
|
+
maturityDate: product.maturityDate,
|
|
440
|
+
NAISC: NAISCCode,
|
|
441
|
+
...(await this.getProductBalances(product._id.toString(), isRevolver, date)),
|
|
442
|
+
};
|
|
443
|
+
if (!summaries) {
|
|
444
|
+
return {
|
|
445
|
+
inventoryGrossValue: 0,
|
|
446
|
+
inventoryAdvanceRate: 0,
|
|
447
|
+
inventoryReserves: 0,
|
|
448
|
+
inventoryNet: 0,
|
|
449
|
+
ARGross: 0,
|
|
450
|
+
ARAdvanceRate: 0,
|
|
451
|
+
ARReserves: 0,
|
|
452
|
+
ARNet: 0,
|
|
453
|
+
otherReserves: 0,
|
|
454
|
+
collateralAdjustments: 0,
|
|
455
|
+
totalCollateral: 0,
|
|
456
|
+
loanBalanceRevolver: 0,
|
|
457
|
+
netRevolverAvailability: 0,
|
|
458
|
+
|
|
459
|
+
equipmentCollateral: 0,
|
|
460
|
+
intellectualProperty: 0,
|
|
461
|
+
realEstate: 0,
|
|
462
|
+
bootCollateral: 0,
|
|
463
|
+
termLoanReserves: 0,
|
|
464
|
+
loanTermBalance: 0,
|
|
465
|
+
netTermAvailability: 0,
|
|
466
|
+
participantBalance: 0,
|
|
467
|
+
...(await this.getProductBalances(product._id.toString(), isRevolver, date)),
|
|
468
|
+
...productMainData,
|
|
469
|
+
} as IBankReportData;
|
|
470
|
+
} else {
|
|
471
|
+
|
|
472
|
+
const balances = await this.getProductBalances(product._id.toString(), isRevolver, date);
|
|
473
|
+
if (useStoredBalance) {
|
|
474
|
+
const bbc = await this.collateralsService.getLatestBBC(borrowerId, date);
|
|
475
|
+
if (bbc) {
|
|
476
|
+
const savedData = await this.signsService.getSavedData(bbc._id.toString());
|
|
477
|
+
if (savedData.loanBalances?.REVOLVER) {
|
|
478
|
+
balances.loanBalanceRevolver = savedData.loanBalances?.REVOLVER;
|
|
479
|
+
balances.loanTermBalance = savedData.loanBalances?.TERM;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const inventoryGrossValue = isRevolver ? getInventoryGrossValue(summaries.inventory) : 0;
|
|
484
|
+
const inventoryAdvanceRate = isRevolver ? getInventoryAdvanceRate(summaries.inventory) : 0;
|
|
485
|
+
const inventoryReserves = isRevolver ? getInventoryReservesValue(summaries.reserve) : 0;
|
|
486
|
+
const inventoryNet = new Decimal(inventoryAdvanceRate).sub(inventoryReserves).toNumber();
|
|
487
|
+
const ARGross = isRevolver ? getARGross(summaries.receivable) : 0;
|
|
488
|
+
const ARAdvanceRate = isRevolver ? getARAdvanceRate(summaries.receivable) : 0;
|
|
489
|
+
const ARReserves = isRevolver ? summaries.reserve[EReserveTypes.RECEIVABLES].amount : 0;
|
|
490
|
+
const ARNet = isRevolver ? (summaries.receivable?.ARAvailability || 0) : 0;
|
|
491
|
+
const otherReserves = isRevolver ? getOtherValue(summaries.reserve) : 0;
|
|
492
|
+
const collateralAdjustments = isRevolver ? await this.getCollateralAdjustmentsForLastSignedBBC(borrowerId, date) : 0;
|
|
493
|
+
const totalCollateral = new Decimal(inventoryAdvanceRate).sub(inventoryReserves).add(ARNet).add(otherReserves).add(collateralAdjustments).toNumber();
|
|
494
|
+
const loanBalanceRevolver = isRevolver ? balances.loanBalanceRevolver : 0;
|
|
495
|
+
const netRevolverAvailability = new Decimal(totalCollateral).sub(loanBalanceRevolver).toNumber();
|
|
496
|
+
|
|
497
|
+
const productEquipmentSummary = !(isRevolver && hasTermProduct)
|
|
498
|
+
? manyTermProduct
|
|
499
|
+
? await this.equipmentService.getEquipmentSummaryForProduct(borrowerId, date, product._id.toString())
|
|
500
|
+
: (await this.equipmentService.getLatestEquipmentForDate(borrowerId, date)).summary
|
|
501
|
+
: null;
|
|
502
|
+
|
|
503
|
+
const equipmentCollateral = productEquipmentSummary ? productEquipmentSummary[EEquipmentTypes.EQUIPMENT].amount : 0;
|
|
504
|
+
const intellectualProperty = productEquipmentSummary ? productEquipmentSummary[EEquipmentTypes.INTELLECTUAL_PROPERTY].amount : 0;
|
|
505
|
+
const realEstate = productEquipmentSummary ? productEquipmentSummary[EEquipmentTypes.REAL_ESTATE].amount : 0;
|
|
506
|
+
const bootCollateral = productEquipmentSummary ? productEquipmentSummary[EEquipmentTypes.BOOT_COLLATERAL].amount : 0;
|
|
507
|
+
const termLoanReserves = !(isRevolver && hasTermProduct) ? summaries.reserve[EReserveTypes.EQUIPMENT].amount : 0;
|
|
508
|
+
const loanTermBalance = !isRevolver ? balances.loanTermBalance : 0;
|
|
509
|
+
const netTermAvailability = new Decimal(equipmentCollateral).sub(termLoanReserves).sub(loanTermBalance).toNumber();
|
|
510
|
+
|
|
511
|
+
const participantBalance = await this.loanChargesService.getParticipationBalance(product.code, date);
|
|
512
|
+
|
|
513
|
+
return {
|
|
514
|
+
...productMainData,
|
|
515
|
+
inventoryGrossValue,
|
|
516
|
+
inventoryAdvanceRate,
|
|
517
|
+
inventoryReserves,
|
|
518
|
+
inventoryNet,
|
|
519
|
+
ARGross,
|
|
520
|
+
ARAdvanceRate,
|
|
521
|
+
ARReserves,
|
|
522
|
+
ARNet,
|
|
523
|
+
otherReserves,
|
|
524
|
+
collateralAdjustments,
|
|
525
|
+
totalCollateral,
|
|
526
|
+
loanBalanceRevolver,
|
|
527
|
+
netRevolverAvailability,
|
|
528
|
+
|
|
529
|
+
equipmentCollateral,
|
|
530
|
+
intellectualProperty,
|
|
531
|
+
realEstate,
|
|
532
|
+
bootCollateral,
|
|
533
|
+
termLoanReserves,
|
|
534
|
+
loanTermBalance,
|
|
535
|
+
netTermAvailability,
|
|
536
|
+
participantBalance,
|
|
537
|
+
} as IBankReportData;
|
|
538
|
+
}
|
|
539
|
+
}));
|
|
540
|
+
}));
|
|
541
|
+
return productsGrouped
|
|
542
|
+
.reduce((acc, group) => [...acc, ...group], [])
|
|
543
|
+
.filter((report) => !!report);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
public async getBalancesCollateralReportExcel(borrowerIds: string[], date: Date) {
|
|
547
|
+
const reportHeader = [
|
|
548
|
+
['PORTFOLIO LOAN BALANCE AND COLLATERAL REPORT'],
|
|
549
|
+
[`RUN DATE ${formatDate(date)}`],
|
|
550
|
+
[''],
|
|
551
|
+
];
|
|
552
|
+
|
|
553
|
+
const keyOrder = [
|
|
554
|
+
'borrowerName',
|
|
555
|
+
'productCode',
|
|
556
|
+
'productType',
|
|
557
|
+
'commitment',
|
|
558
|
+
'startDate',
|
|
559
|
+
'maturityDate',
|
|
560
|
+
'inventoryGrossValue',
|
|
561
|
+
'inventoryAdvanceRate',
|
|
562
|
+
'inventoryReserves',
|
|
563
|
+
'inventoryNet',
|
|
564
|
+
'ARGross',
|
|
565
|
+
'ARAdvanceRate',
|
|
566
|
+
'ARReserves',
|
|
567
|
+
'ARNet',
|
|
568
|
+
'otherReserves',
|
|
569
|
+
'collateralAdjustments',
|
|
570
|
+
'totalCollateral',
|
|
571
|
+
'loanBalanceRevolver',
|
|
572
|
+
'netRevolverAvailability',
|
|
573
|
+
'equipmentCollateral',
|
|
574
|
+
'intellectualProperty',
|
|
575
|
+
'realEstate',
|
|
576
|
+
'bootCollateral',
|
|
577
|
+
'termLoanReserves',
|
|
578
|
+
'loanTermBalance',
|
|
579
|
+
'netTermAvailability',
|
|
580
|
+
'participantBalance',
|
|
581
|
+
'NAISC',
|
|
582
|
+
];
|
|
583
|
+
|
|
584
|
+
const tableHeader: { [K in keyof IBankReportData]: string } = {
|
|
585
|
+
borrowerName: 'Borrower name',
|
|
586
|
+
productCode: 'Product code',
|
|
587
|
+
productType: 'Product type',
|
|
588
|
+
commitment: 'Commitment',
|
|
589
|
+
startDate: 'Start Date',
|
|
590
|
+
maturityDate: 'Maturity Date',
|
|
591
|
+
inventoryGrossValue: 'Inventory Gross Value',
|
|
592
|
+
inventoryAdvanceRate: 'Inventory @ Advance Rate',
|
|
593
|
+
inventoryReserves: 'Inventory Reserves',
|
|
594
|
+
inventoryNet: 'Inventory Net',
|
|
595
|
+
ARGross: 'AR Gross',
|
|
596
|
+
ARAdvanceRate: 'AR Advance Rate',
|
|
597
|
+
ARReserves: 'AR Reserves',
|
|
598
|
+
ARNet: 'AR Net',
|
|
599
|
+
otherReserves: 'Other Reserves',
|
|
600
|
+
collateralAdjustments: 'Collateral Adjustments',
|
|
601
|
+
totalCollateral: 'Total Revolver Collateral',
|
|
602
|
+
loanBalanceRevolver: 'LOAN BALANCE Revolver',
|
|
603
|
+
netRevolverAvailability: 'Available to borrow',
|
|
604
|
+
equipmentCollateral: 'Equipment Collateral',
|
|
605
|
+
intellectualProperty: 'Intellectual Property',
|
|
606
|
+
realEstate: 'Real Estate',
|
|
607
|
+
bootCollateral: 'Boot Collateral',
|
|
608
|
+
termLoanReserves: 'Term Loan Reserves (total)',
|
|
609
|
+
loanTermBalance: 'LOAN BALANCE (Term products only)',
|
|
610
|
+
netTermAvailability: 'NET TERM AVAILABILITY',
|
|
611
|
+
participantBalance: 'Participant balance',
|
|
612
|
+
NAISC: 'NAISC Code',
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
const reportData = await this.generateBankPortfolioSummary(borrowerIds, date, {
|
|
616
|
+
useSignedBBC: true,
|
|
617
|
+
useStoredBalance: false,
|
|
618
|
+
});
|
|
619
|
+
const headerArray = Object.values(reorderObject(tableHeader, keyOrder));
|
|
620
|
+
const dataAsArrays = reportData.map((row) => Object.values(reorderObject(row, keyOrder)));
|
|
621
|
+
return await this.uploadsService.convertDataToFile([{ portfolio: [...reportHeader, headerArray, ...dataAsArrays] }]);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async getLedger(productIds: string[], startDate: Date, endDate: Date, reportType: ELedgerReportType, showFloatedBalance = true) {
|
|
625
|
+
const params: ReportLedgerParams = {
|
|
626
|
+
endDate,
|
|
627
|
+
productIds,
|
|
628
|
+
reportType,
|
|
629
|
+
startDate,
|
|
630
|
+
};
|
|
631
|
+
const options: ReportLedgerOptions = { showBalances: showFloatedBalance, showFloatedBalance };
|
|
632
|
+
return getLedger(params, options);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
async getInvestorSummaryReport(selectedBorrowerIds: string[], start: Date, end: Date) {
|
|
636
|
+
const startFormatted = dayjs(start).format(defaultDateFormat);
|
|
637
|
+
const endFormatted = dayjs(end).format(defaultDateFormat);
|
|
638
|
+
const keyOrder = [
|
|
639
|
+
'clientName',
|
|
640
|
+
'productName',
|
|
641
|
+
'maturityDate',
|
|
642
|
+
'commitmentAmount',
|
|
643
|
+
'balanceEnd',
|
|
644
|
+
'participationBalanceEnd',
|
|
645
|
+
'companyExposure',
|
|
646
|
+
'netAvailable',
|
|
647
|
+
'collectionsBetweenStartEnd',
|
|
648
|
+
'disbursementsBetweenStartEnd',
|
|
649
|
+
'availableToBorrow',
|
|
650
|
+
'ARNet',
|
|
651
|
+
'inventoryNet',
|
|
652
|
+
'otherCollateral',
|
|
653
|
+
'otherReservesAndAdjustments',
|
|
654
|
+
'totalRevolverCollateral',
|
|
655
|
+
'collectionsBetweenBeginningEnd',
|
|
656
|
+
'disbursementsBetweenBeginningEnd',
|
|
657
|
+
];
|
|
658
|
+
|
|
659
|
+
const header = [
|
|
660
|
+
['Report period'],
|
|
661
|
+
['From', startFormatted],
|
|
662
|
+
['To', endFormatted],
|
|
663
|
+
[''],
|
|
664
|
+
];
|
|
665
|
+
|
|
666
|
+
const tableHeader: { [K in keyof IInvestorSummaryDataRow]: string } = {
|
|
667
|
+
clientName: 'Client name',
|
|
668
|
+
productName: 'Product name',
|
|
669
|
+
maturityDate: 'Maturity date',
|
|
670
|
+
commitmentAmount: 'Commitment amount',
|
|
671
|
+
balanceEnd: `Balance as at ${endFormatted}`,
|
|
672
|
+
participationBalanceEnd: `Participation balance as at ${endFormatted}`,
|
|
673
|
+
companyExposure: 'Exposure',
|
|
674
|
+
netAvailable: 'Net available',
|
|
675
|
+
collectionsBetweenStartEnd: `Collections between ${startFormatted} & ${endFormatted}`,
|
|
676
|
+
disbursementsBetweenStartEnd: `Disbursements between ${startFormatted} & ${endFormatted}`,
|
|
677
|
+
netRevolverAvailability: 'Available to borrow',
|
|
678
|
+
ARNet: 'AR net',
|
|
679
|
+
inventoryNet: 'Inventory net',
|
|
680
|
+
otherCollateral: 'Other collateral (sum of equipment, ip, real estate, boot )',
|
|
681
|
+
otherReservesAndAdjustments: 'Other Reserves & Adjustments',
|
|
682
|
+
totalRevolver: 'Total revolver collateral + total equipment & ip collateral)',
|
|
683
|
+
collectionsBetweenBeginningEnd: `Collections between beginning to ${endFormatted}`,
|
|
684
|
+
disbursementsBetweenBeginningEnd: `Disbursements between beginning to ${endFormatted}`,
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
const data = await this.investorSummaryService.getInvestorSummaryData(selectedBorrowerIds, start, end);
|
|
688
|
+
const headerArray = Object.values(reorderObject(tableHeader, keyOrder));
|
|
689
|
+
const dataAsArrays = data.map((row) => Object.values(reorderObject(row, keyOrder)));
|
|
690
|
+
return [{ report: [...header, headerArray, ...dataAsArrays] }];
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function reorderObject(obj: object, keyOrder: string[]): object {
|
|
695
|
+
const reorderedObject: object = {};
|
|
696
|
+
keyOrder.forEach(key => {
|
|
697
|
+
if (Object.hasOwn(obj, key)) {
|
|
698
|
+
reorderedObject[key] = obj[key];
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
return reorderedObject;
|
|
702
|
+
}
|