"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReportsService = void 0;
const dayjs_1 = __importDefault(require("dayjs"));
const decimal_js_1 = __importDefault(require("decimal.js"));
const Borrower_model_1 = require("../models/Borrower.model");
const date_helper_1 = require("../helpers/date.helper");
const loan_types_enum_1 = require("../enums/loan-types.enum");
const reserve_types_enum_1 = require("../enums/reserve-types.enum");
const equipment_types_enum_1 = require("../enums/equipment-types.enum");
const reports_db_1 = require("../db/reports.db");
const pdf_service_1 = require("./pdf.service");
const createReportItemFromInventory = (item) => {
    return {
        name: item.inventoryName,
        grossValue: -item.totalValue,
        advanceRate: item.advanceRate * 100,
        netValue: -item.availability,
    };
};
const createReportItemFromEquipment = (items) => {
    const titleMap = {
        EQUIPMENT: 'Equipment',
        INTELLECTUAL_PROPERTY: 'Intellectual property',
        REAL_ESTATE: 'Real estate',
        BOOT_COLLATERAL: 'Boot collateral',
    };
    return Object.entries(titleMap).map(([key, title]) => {
        return {
            name: title,
            grossValue: items[key].amount,
            advanceRate: items[key].advanceRate,
            netValue: items[key].availability,
        };
    });
};
const createReportItemFromReserve = (item, reserveName) => {
    return {
        name: reserveName,
        grossValue: 0,
        advanceRate: 0,
        netValue: -item.amount,
    };
};
const createReportItemsFromReceivable = (receivable) => {
    const getArUninsured = () => {
        return receivable
            ? {
                grossValue: receivable.uninsuredComponent,
                advanceRate: receivable.uninsuredComponent === 0 ? 0 : new decimal_js_1.default(receivable.uninsuredAvailability).div(receivable.uninsuredComponent).mul(100).toDP(2).toNumber(),
                netValue: receivable.uninsuredAvailability,
            }
            : {
                grossValue: 0,
                advanceRate: 0,
                netValue: 0,
            };
    };
    const getArInsured = () => {
        return receivable
            ? {
                grossValue: receivable.insuredComponent,
                advanceRate: receivable.insuredComponent === 0 ? 0 : new decimal_js_1.default(receivable.insuredAvailability).div(receivable.insuredComponent).mul(100).toDP(2).toNumber(),
                netValue: receivable.insuredAvailability,
            }
            : {
                grossValue: 0,
                advanceRate: 0,
                netValue: 0,
            };
    };
    return {
        arUninsured: {
            name: 'AR Uninsured',
            ...getArUninsured(),
        },
        arInsured: {
            name: 'AR Insured',
            ...getArInsured(),
        },
    };
};
const createTotalRows = (allResults, productType, loanBalance) => {
    const productTypeTitles = {
        REVOLVER: {
            totalCollateral: 'TOTAL REVOLVING COLLATERAL',
            loanBalance: 'LOAN BALANCE (Revolving products only)',
            netAvailability: 'NET REVOLVER AVAILABILITY',
        },
        TERM: {
            totalCollateral: 'TOTAL TERM COLLATERAL',
            loanBalance: 'LOAN BALANCE (Term products only)',
            netAvailability: 'NET TERM AVAILABILITY',
        },
    };
    const totalCollateralRow = allResults.reduce((acc, item) => {
        acc.grossValue = new decimal_js_1.default(acc.grossValue).plus(item.grossValue).toNumber();
        acc.netValue = new decimal_js_1.default(acc.netValue).plus(item.netValue).toNumber();
        acc.advanceRate = item.grossValue === 0 ? 0 : new decimal_js_1.default(acc.netValue).div(item.grossValue).toDP(2).toNumber();
        return acc;
    }, {
        name: productTypeTitles[productType].totalCollateral,
        grossValue: 0,
        advanceRate: 0,
        netValue: 0,
    });
    const loanBalanceRow = {
        name: productTypeTitles[productType].loanBalance,
        grossValue: loanBalance,
        advanceRate: 0,
        netValue: loanBalance,
    };
    const netAvailabilityRow = {
        name: productTypeTitles[productType].netAvailability,
        grossValue: 0,
        advanceRate: 0,
        netValue: new decimal_js_1.default(totalCollateralRow.netValue).sub(loanBalanceRow.netValue).toNumber(),
    };
    return { totalCollateralRow, loanBalanceRow, netAvailabilityRow };
};
const getInventoryGrossValue = (inventory) => {
    const foundInv = inventory?.find((s) => s.inventoryName === 'TOTAL');
    if (foundInv) {
        return foundInv.totalValue;
    }
    return 0;
};
const getInventoryAdvanceRate = (inventory) => {
    const foundInv = inventory?.find((s) => s.inventoryName === 'TOTAL');
    if (foundInv) {
        return foundInv.availability;
    }
    return 0;
};
const getInventoryReservesValue = (reserve) => {
    return reserve[reserve_types_enum_1.EReserveTypes.INVENTORY]?.amount ?? 0;
};
const getARGross = (receivable) => {
    return !receivable ? 0 : new decimal_js_1.default(receivable.uninsuredComponent || 0).add(receivable.insuredComponent || 0).toNumber();
};
const getARAdvanceRate = (receivable) => {
    return !receivable ? 0 : new decimal_js_1.default(receivable.uninsuredAvailability || 0).add(receivable.insuredAvailability || 0).toNumber();
};
const getOtherValue = (reserves) => {
    return Object
        .entries(reserves)
        .reduce((acc, [key, el]) => {
        if (key === reserve_types_enum_1.EReserveTypes.EQUIPMENT ||
            key === reserve_types_enum_1.EReserveTypes.INVENTORY ||
            key === reserve_types_enum_1.EReserveTypes.RECEIVABLES) {
            return acc;
        }
        return new decimal_js_1.default(acc || 0).sub(el.amount).toNumber();
    }, 0);
};
class ReportsService {
    availabilityService;
    borrowerService;
    collateralAdjustmentsService;
    collateralsService;
    equipmentService;
    loanChargesService;
    loanTransactionsService;
    signsService;
    uploadsService;
    investorSummaryService;
    margin = pdf_service_1.defaultPDFPageMarginSize;
    constructor(availabilityService, borrowerService, collateralAdjustmentsService, collateralsService, equipmentService, loanChargesService, loanTransactionsService, signsService, uploadsService, investorSummaryService) {
        this.availabilityService = availabilityService;
        this.borrowerService = borrowerService;
        this.collateralAdjustmentsService = collateralAdjustmentsService;
        this.collateralsService = collateralsService;
        this.equipmentService = equipmentService;
        this.loanChargesService = loanChargesService;
        this.loanTransactionsService = loanTransactionsService;
        this.signsService = signsService;
        this.uploadsService = uploadsService;
        this.investorSummaryService = investorSummaryService;
    }
    async getCollateralAdjustmentsForLastSignedBBC(borrowerId, date) {
        const lastSignedBBC = await this.signsService.getLatestSignedBBCDate(borrowerId, date);
        if (!lastSignedBBC) {
            return 0;
        }
        const summary = await this.collateralAdjustmentsService.getCollateralAdjustmentSummary(lastSignedBBC._id.toString());
        return Object.values(summary).reduce((acc, summaryRow) => (new decimal_js_1.default(acc).add(summaryRow.amount).toNumber()), 0);
    }
    ;
    async getProductBalances(productId, isRevolver, date) {
        const lastTransaction = await this.loanTransactionsService.getLastTransactionForDate(productId, date);
        const balance = lastTransaction ? lastTransaction.balance : 0;
        const availability = -balance;
        const balances = {
            loanBalanceRevolver: isRevolver ? balance : 0,
            netRevolverAvailability: isRevolver ? availability : 0,
            loanTermBalance: isRevolver ? 0 : balance,
            netTermAvailability: isRevolver ? 0 : availability,
        };
        return balances;
    }
    ;
    async getBorrowerAndProducts(borrowerId, date, useSignedBBC = false, requireBBC = true) {
        const borrower = await Borrower_model_1.BorrowerModel.findById(borrowerId);
        if (!borrower) {
            return null;
        }
        const latestBBC = useSignedBBC
            ? await this.signsService.getLatestSignedBBCDate(borrowerId, date)
            : await this.collateralsService.getLatestBBC(borrowerId, date);
        if (!latestBBC && requireBBC) {
            return null;
        }
        const summaries = latestBBC ? await this.availabilityService.getAllSummaries(latestBBC._id.toString(), null) : null;
        const products = await this.loanChargesService.getLoanProducts(borrowerId);
        return { borrower, latestBBC, summaries, products };
    }
    async generatePortfolioSummary(borrowerIds, date) {
        if (borrowerIds.length === 0) {
            return {};
        }
        const allResults = {};
        await Promise.all(borrowerIds.map(async (borrowerId) => {
            const borrowerData = await this.getBorrowerAndProducts(borrowerId, date, true);
            if (!borrowerData) {
                return;
            }
            const { borrower, latestBBC, summaries, products } = borrowerData;
            if (!borrower) {
                return;
            }
            const revolverProduct = products.find((product) => product.type === loan_types_enum_1.ELoanTypes.REVOLVER && (0, date_helper_1.isProductActive)(product.startDate, product.deactivationDate, date));
            const termProduct = products.find((product) => product.type === loan_types_enum_1.ELoanTypes.TERM);
            let revolverDataGroup = null;
            if (revolverProduct) {
                const inventoryItems = summaries.inventory.map(createReportItemFromInventory);
                const inventoryReserve = createReportItemFromReserve(summaries.reserve['INVENTORY'], 'Inventory Reserves');
                const ARReserve = createReportItemFromReserve(summaries.reserve['RECEIVABLES'], 'AR Reserves');
                const otherReserve = createReportItemFromReserve(summaries.reserve['OTHER'], 'Other non-equipment reserves');
                const { arUninsured, arInsured } = createReportItemsFromReceivable(summaries.receivable);
                const revolverItems = [...inventoryItems, inventoryReserve, arUninsured, arInsured, ARReserve, otherReserve];
                const revolverBalance = await this.loanChargesService.getLoanProductBalance(revolverProduct._id.toString(), date);
                const { totalCollateralRow: totalCollateralRowRevolver, loanBalanceRow: loanBalanceRowRevolver, netAvailabilityRow: netAvailabilityRowRevolver, } = createTotalRows(revolverItems, 'REVOLVER', revolverBalance.balance);
                revolverDataGroup = {
                    NAISCCode: '',
                    productCode: '',
                    isCompliant: false,
                    isExternalAppraisal: false,
                    items: [...revolverItems, totalCollateralRowRevolver, loanBalanceRowRevolver, netAvailabilityRowRevolver],
                };
            }
            let termDataGroup = null;
            if (termProduct) {
                const equipmentItems = createReportItemFromEquipment(summaries.equipment);
                const termReserve = createReportItemFromReserve(summaries.reserve['EQUIPMENT'], 'Term Loan Reserves (total)');
                const termItems = [...equipmentItems, termReserve];
                const termBalance = await this.loanChargesService.getLoanProductBalance(termProduct._id.toString(), date);
                const { totalCollateralRow: totalCollateralRowTerm, loanBalanceRow: loanBalanceRowTerm, netAvailabilityRow: netAvailabilityRowTerm, } = createTotalRows(termItems, 'TERM', termBalance.balance);
                termDataGroup = {
                    NAISCCode: '',
                    productCode: '',
                    isCompliant: false,
                    isExternalAppraisal: false,
                    items: [...termItems, totalCollateralRowTerm, loanBalanceRowTerm, netAvailabilityRowTerm],
                };
            }
            allResults[borrowerId] = {
                borrowerName: borrower.name,
                bbcDate: latestBBC.bbcDate,
                revolverDataGroup,
                termDataGroup,
            };
        }));
        return allResults;
    }
    async getPortfolioSummaryExcel(borrowerIds, date) {
        const report = await this.generatePortfolioSummary(borrowerIds, date);
        const emptyRow = [['']];
        const reportHeader = [
            ['PORTFOLIO LOAN BALANCE AND COLLATERAL REPORT'],
            [`RUN DATE ${(0, date_helper_1.convertDateToFormat)(date)}`],
            [''],
        ];
        const reportToCovert = Object.values(report).reduce((acc, borrowerData) => {
            const headers = [
                [`LOAN BALANCE AND COLLATERAL REPORT ${borrowerData.borrowerName}, Last BBC date - ${(0, date_helper_1.convertDateToFormat)(borrowerData.bbcDate)}`],
                ['', 'Gross Value', 'Advance Rate', 'Net Value'],
            ];
            const convertToExcel = (dataGroup) => {
                if (!dataGroup) {
                    return [];
                }
                return dataGroup.items.reduce((acc, revolverItem) => {
                    if (revolverItem.name === 'TOTAL') {
                        return acc;
                    }
                    return [...acc, [...Object.values(revolverItem).map((v) => v === 0 ? '-' : v)]];
                }, []);
            };
            const revolverData = convertToExcel(borrowerData.revolverDataGroup);
            const termData = convertToExcel(borrowerData.termDataGroup);
            return [...acc, ...headers, ...revolverData, ...emptyRow, ...termData, ...emptyRow, ...emptyRow];
        }, [...reportHeader]);
        return await this.uploadsService.convertDataToFile([{ portfolio: reportToCovert }]);
    }
    async generateBankPortfolioSummary(borrowerIds, date, { useSignedBBC, useStoredBalance, } = { useSignedBBC: true, useStoredBalance: false }) {
        const dateForBalance = dayjs_1.default.utc(date).endOf('day').toDate();
        const productsGrouped = await Promise.all(borrowerIds.map(async (borrowerId) => {
            const borrowerData = await this.getBorrowerAndProducts(borrowerId, date, useSignedBBC, false);
            if (!borrowerData) {
                return [];
            }
            const { borrower, summaries, products } = borrowerData;
            if (!borrower) {
                return [];
            }
            const borrowerSettings = await this.borrowerService.getBorrowerSettings(borrowerId);
            const borrowerOptions = borrowerSettings.data.options;
            const NAISCCodeOption = borrowerOptions.find((option) => option['dataName'] === 'NAISC Code');
            const NAISCCode = NAISCCodeOption ? NAISCCodeOption.dataValue : '';
            const hasTermProduct = products.some((product) => product.type === loan_types_enum_1.ELoanTypes.TERM);
            const manyTermProduct = products.filter((product) => product.type === loan_types_enum_1.ELoanTypes.TERM).length > 1;
            return await Promise.all(products.map(async (product) => {
                if (product.masterLoanProductId != null) {
                    return null;
                }
                if ((0, dayjs_1.default)(product.deactivationDate).isBefore((0, dayjs_1.default)(date))) {
                    return null;
                }
                if ((0, dayjs_1.default)(product.startDate).isAfter((0, dayjs_1.default)(date))) {
                    return null;
                }
                const isRevolver = product.type === loan_types_enum_1.ELoanTypes.REVOLVER;
                const productMainData = {
                    borrowerId,
                    borrowerName: borrower.name,
                    productCode: product.code,
                    productType: product.type,
                    commitment: product.commitment,
                    startDate: product.startDate,
                    maturityDate: product.maturityDate,
                    NAISC: NAISCCode,
                    ...(await this.getProductBalances(product._id.toString(), isRevolver, dateForBalance)),
                };
                if (!summaries) {
                    return {
                        inventoryGrossValue: 0,
                        inventoryAdvanceRate: 0,
                        inventoryReserves: 0,
                        inventoryNet: 0,
                        ARGross: 0,
                        ARAdvanceRate: 0,
                        ARReserves: 0,
                        ARNet: 0,
                        otherReserves: 0,
                        collateralAdjustments: 0,
                        totalCollateral: 0,
                        loanBalanceRevolver: 0,
                        netRevolverAvailability: 0,
                        equipmentCollateral: 0,
                        intellectualProperty: 0,
                        realEstate: 0,
                        bootCollateral: 0,
                        termLoanReserves: 0,
                        loanTermBalance: 0,
                        netTermAvailability: 0,
                        participantBalance: 0,
                        ...(await this.getProductBalances(product._id.toString(), isRevolver, dateForBalance)),
                        ...productMainData,
                    };
                }
                else {
                    const balances = await this.getProductBalances(product._id.toString(), isRevolver, dateForBalance);
                    if (useStoredBalance) {
                        const bbc = await this.collateralsService.getLatestBBC(borrowerId, date);
                        if (bbc) {
                            const savedData = await this.signsService.getSavedData(bbc._id.toString());
                            if (savedData.loanBalances?.REVOLVER) {
                                balances.loanBalanceRevolver = savedData.loanBalances?.REVOLVER;
                                balances.loanTermBalance = savedData.loanBalances?.TERM;
                            }
                        }
                    }
                    const inventoryGrossValue = isRevolver ? getInventoryGrossValue(summaries.inventory) : 0;
                    const inventoryAdvanceRate = isRevolver ? getInventoryAdvanceRate(summaries.inventory) : 0;
                    const inventoryReserves = isRevolver ? getInventoryReservesValue(summaries.reserve) : 0;
                    const inventoryNet = new decimal_js_1.default(inventoryAdvanceRate).sub(inventoryReserves).toNumber();
                    const ARGross = isRevolver ? getARGross(summaries.receivable) : 0;
                    const ARAdvanceRate = isRevolver ? getARAdvanceRate(summaries.receivable) : 0;
                    const ARReserves = isRevolver ? summaries.reserve[reserve_types_enum_1.EReserveTypes.RECEIVABLES].amount : 0;
                    const ARNet = isRevolver ? (summaries.receivable?.ARAvailability || 0) : 0;
                    const otherReserves = isRevolver ? getOtherValue(summaries.reserve) : 0;
                    const collateralAdjustments = isRevolver ? await this.getCollateralAdjustmentsForLastSignedBBC(borrowerId, date) : 0;
                    const totalCollateral = new decimal_js_1.default(inventoryAdvanceRate).sub(inventoryReserves).add(ARNet).add(otherReserves).add(collateralAdjustments).toNumber();
                    const loanBalanceRevolver = isRevolver ? balances.loanBalanceRevolver : 0;
                    const netRevolverAvailability = new decimal_js_1.default(totalCollateral).sub(loanBalanceRevolver).toNumber();
                    const productEquipmentSummary = (isRevolver && hasTermProduct)
                        ? null
                        : manyTermProduct
                            ? (await this.equipmentService.getLatestEquipmentForDate(borrowerId, date)).summary
                            : await this.equipmentService.getEquipmentSummaryForProduct(borrowerId, date, product._id.toString());
                    const equipmentCollateral = productEquipmentSummary ? productEquipmentSummary[equipment_types_enum_1.EEquipmentTypes.EQUIPMENT].amount : 0;
                    const intellectualProperty = productEquipmentSummary ? productEquipmentSummary[equipment_types_enum_1.EEquipmentTypes.INTELLECTUAL_PROPERTY].amount : 0;
                    const realEstate = productEquipmentSummary ? productEquipmentSummary[equipment_types_enum_1.EEquipmentTypes.REAL_ESTATE].amount : 0;
                    const bootCollateral = productEquipmentSummary ? productEquipmentSummary[equipment_types_enum_1.EEquipmentTypes.BOOT_COLLATERAL].amount : 0;
                    const termLoanReserves = !(isRevolver && hasTermProduct) ? summaries.reserve[reserve_types_enum_1.EReserveTypes.EQUIPMENT].amount : 0;
                    const loanTermBalance = !isRevolver ? balances.loanTermBalance : 0;
                    const netTermAvailability = new decimal_js_1.default(equipmentCollateral).sub(termLoanReserves).sub(loanTermBalance).toNumber();
                    const participantBalance = await this.loanChargesService.getParticipationBalance(product.code, date);
                    return {
                        ...productMainData,
                        inventoryGrossValue,
                        inventoryAdvanceRate,
                        inventoryReserves,
                        inventoryNet,
                        ARGross,
                        ARAdvanceRate,
                        ARReserves,
                        ARNet,
                        otherReserves,
                        collateralAdjustments,
                        totalCollateral,
                        loanBalanceRevolver,
                        netRevolverAvailability,
                        equipmentCollateral,
                        intellectualProperty,
                        realEstate,
                        bootCollateral,
                        termLoanReserves,
                        loanTermBalance,
                        netTermAvailability,
                        participantBalance,
                    };
                }
            }));
        }));
        return productsGrouped
            .reduce((acc, group) => [...acc, ...group], [])
            .filter((report) => !!report);
    }
    async getBalancesCollateralReportExcel(borrowerIds, date) {
        const reportHeader = [
            ['PORTFOLIO LOAN BALANCE AND COLLATERAL REPORT'],
            [`RUN DATE ${(0, date_helper_1.convertDateToFormat)(date)}`],
            [''],
        ];
        const keyOrder = [
            'borrowerName',
            'productCode',
            'productType',
            'commitment',
            'startDate',
            'maturityDate',
            'inventoryGrossValue',
            'inventoryAdvanceRate',
            'inventoryReserves',
            'inventoryNet',
            'ARGross',
            'ARAdvanceRate',
            'ARReserves',
            'ARNet',
            'otherReserves',
            'collateralAdjustments',
            'totalCollateral',
            'loanBalanceRevolver',
            'netRevolverAvailability',
            'equipmentCollateral',
            'intellectualProperty',
            'realEstate',
            'bootCollateral',
            'termLoanReserves',
            'loanTermBalance',
            'netTermAvailability',
            'participantBalance',
            'NAISC',
        ];
        const tableHeader = {
            borrowerName: 'Borrower name',
            productCode: 'Product code',
            productType: 'Product type',
            commitment: 'Commitment',
            startDate: 'Start Date',
            maturityDate: 'Maturity Date',
            inventoryGrossValue: 'Inventory Gross Value',
            inventoryAdvanceRate: 'Inventory @ Advance Rate',
            inventoryReserves: 'Inventory Reserves',
            inventoryNet: 'Inventory Net',
            ARGross: 'AR Gross',
            ARAdvanceRate: 'AR Advance Rate',
            ARReserves: 'AR Reserves',
            ARNet: 'AR Net',
            otherReserves: 'Other Reserves',
            collateralAdjustments: 'Collateral Adjustments',
            totalCollateral: 'Total Revolver Collateral',
            loanBalanceRevolver: 'LOAN BALANCE Revolver',
            netRevolverAvailability: 'Available to borrow',
            equipmentCollateral: 'Equipment Collateral',
            intellectualProperty: 'Intellectual Property',
            realEstate: 'Real Estate',
            bootCollateral: 'Boot Collateral',
            termLoanReserves: 'Term Loan Reserves (total)',
            loanTermBalance: 'LOAN BALANCE (Term products only)',
            netTermAvailability: 'NET TERM AVAILABILITY',
            participantBalance: 'Participant balance',
            NAISC: 'NAISC Code',
        };
        const reportData = await this.generateBankPortfolioSummary(borrowerIds, date, {
            useSignedBBC: true,
            useStoredBalance: false,
        });
        const headerArray = Object.values(reorderObject(tableHeader, keyOrder));
        const dataAsArrays = reportData.map((row) => Object.values(reorderObject(row, keyOrder)));
        return await this.uploadsService.convertDataToFile([{ portfolio: [...reportHeader, headerArray, ...dataAsArrays] }]);
    }
    async getLedger(productIds, startDate, endDate, reportType, showFloatedBalance = true) {
        const params = {
            endDate,
            productIds,
            reportType,
            startDate,
        };
        const options = { showBalances: showFloatedBalance, showFloatedBalance };
        return (0, reports_db_1.getLedger)(params, options);
    }
    async getInvestorSummaryReport(selectedBorrowerIds, start, end) {
        const startFormatted = (0, dayjs_1.default)(start).format(date_helper_1.defaultDateFormat);
        const endFormatted = (0, dayjs_1.default)(end).format(date_helper_1.defaultDateFormat);
        const keyOrder = [
            'clientName',
            'productName',
            'maturityDate',
            'commitmentAmount',
            'balanceEnd',
            'participationBalanceEnd',
            'companyExposure',
            'netAvailable',
            'collectionsBetweenStartEnd',
            'disbursementsBetweenStartEnd',
            'availableToBorrow',
            'ARNet',
            'inventoryNet',
            'otherCollateral',
            'otherReservesAndAdjustments',
            'totalRevolverCollateral',
            'collectionsBetweenBeginningEnd',
            'disbursementsBetweenBeginningEnd',
        ];
        const header = [
            ['Report period'],
            ['From', startFormatted],
            ['To', endFormatted],
            [''],
        ];
        const tableHeader = {
            clientName: 'Client name',
            productName: 'Product name',
            maturityDate: 'Maturity date',
            commitmentAmount: 'Commitment amount',
            balanceEnd: `Balance as at ${endFormatted}`,
            participationBalanceEnd: `Participation balance as at ${endFormatted}`,
            companyExposure: 'Exposure',
            netAvailable: 'Net available',
            collectionsBetweenStartEnd: `Collections between ${startFormatted} & ${endFormatted}`,
            disbursementsBetweenStartEnd: `Disbursements between ${startFormatted} & ${endFormatted}`,
            netRevolverAvailability: 'Available to borrow',
            ARNet: 'AR net',
            inventoryNet: 'Inventory net',
            otherCollateral: 'Other collateral (sum of equipment, ip, real estate, boot )',
            otherReservesAndAdjustments: 'Other Reserves & Adjustments',
            totalRevolver: 'Total revolver collateral + total equipment & ip collateral)',
            collectionsBetweenBeginningEnd: `Collections between beginning to ${endFormatted}`,
            disbursementsBetweenBeginningEnd: `Disbursements between beginning to ${endFormatted}`,
        };
        const data = await this.investorSummaryService.getInvestorSummaryData(selectedBorrowerIds, start, end);
        const headerArray = Object.values(reorderObject(tableHeader, keyOrder));
        const dataAsArrays = data.map((row) => Object.values(reorderObject(row, keyOrder)));
        return [{ report: [...header, headerArray, ...dataAsArrays] }];
    }
}
exports.ReportsService = ReportsService;
function reorderObject(obj, keyOrder) {
    const reorderedObject = {};
    keyOrder.forEach(key => {
        if (Object.hasOwn(obj, key)) {
            reorderedObject[key] = obj[key];
        }
    });
    return reorderedObject;
}
