"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    getFormattedCoverageAmountPerInsurancePlanForInvoice: function() {
        return getFormattedCoverageAmountPerInsurancePlanForInvoice;
    },
    getInsuranceCoverageTotalAmount: function() {
        return getInsuranceCoverageTotalAmount;
    },
    getInvoiceSummary: function() {
        return getInvoiceSummary;
    },
    isInvoiceEditable: function() {
        return isInvoiceEditable;
    }
});
const _decimal = /*#__PURE__*/ _interop_require_default(require("decimal.js"));
const _constants = require("@tamanu/constants");
const _display = require("./display");
const _invoiceItem = require("./invoiceItem");
const _discount = require("./discount");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
const isInvoiceEditable = (invoice)=>invoice.status === _constants.INVOICE_STATUSES.IN_PROGRESS;
const getInsuranceCoverageTotalAmount = (invoiceItems)=>{
    return invoiceItems.reduce((sum, item)=>{
        const discountedPrice = (0, _invoiceItem.getInvoiceItemTotalDiscountedPrice)(item) || 0;
        // Apply insurance coverage only to items whose product is explicitly insurable
        if (!item?.product?.insurable || !item.insurancePlanItems) {
            return sum;
        }
        const totalItemInsurance = item.insurancePlanItems.reduce((itemSum, itemPlan)=>{
            const coverageForRow = (0, _invoiceItem.getItemSingleInsuranceCoverageAmount)(discountedPrice, item, itemPlan);
            return itemSum.plus(coverageForRow);
        }, new _decimal.default(0));
        const cappedItemInsurance = totalItemInsurance > discountedPrice ? discountedPrice : totalItemInsurance;
        return sum.plus(cappedItemInsurance);
    }, new _decimal.default(0));
};
const getFormattedCoverageAmountPerInsurancePlanForInvoice = (invoice)=>{
    const insurancePlans = invoice.insurancePlans || [];
    const items = invoice.items || [];
    const planCoverageTotals = new Map(insurancePlans.map((p)=>[
            p.id,
            new _decimal.default(0)
        ]));
    for (const item of items){
        if (!item?.product?.insurable || !item.insurancePlanItems?.length) {
            continue;
        }
        const discountedPrice = (0, _invoiceItem.getInvoiceItemTotalDiscountedPrice)(item) || 0;
        for (const planItem of item.insurancePlanItems){
            if (planCoverageTotals.has(planItem.id)) {
                const coverageAmount = (0, _invoiceItem.getItemSingleInsuranceCoverageAmount)(discountedPrice, item, planItem);
                planCoverageTotals.set(planItem.id, planCoverageTotals.get(planItem.id).plus(coverageAmount));
            }
        }
    }
    return insurancePlans.map((plan)=>{
        const totalCoverage = planCoverageTotals.get(plan.id);
        return {
            id: plan.id,
            name: plan.name,
            code: plan.code,
            totalCoverage: (0, _display.formatDisplayPrice)(totalCoverage.negated())
        };
    });
};
const getInvoiceSummary = (invoice)=>{
    invoice = JSON.parse(JSON.stringify(invoice)); // deep clone to convert sequelize entity to plain objects
    const invoiceItemsUndiscountedTotal = invoice.items.reduce((sum, item)=>sum.plus((0, _invoiceItem.getInvoiceItemTotalPrice)(item) || 0), new _decimal.default(0));
    const invoiceItemsTotal = invoice.items.reduce((sum, item)=>sum.plus((0, _invoiceItem.getInvoiceItemTotalDiscountedPrice)(item) || 0), new _decimal.default(0));
    const insuranceCoverageTotal = getInsuranceCoverageTotalAmount(invoice.items);
    const patientSubtotal = invoiceItemsTotal.minus(insuranceCoverageTotal);
    const discountTotal = (0, _discount.getInvoiceLevelDiscountAmount)(invoice.discount, patientSubtotal);
    // Calculate item adjustments here to be used in the printout
    const itemAdjustmentsTotal = invoice.items.reduce((sum, item)=>sum.plus((0, _invoiceItem.getItemAdjustmentAmount)(item) || 0), new _decimal.default(0));
    const patientTotal = patientSubtotal.minus(discountTotal);
    // Calculate payments as well
    const payments = invoice?.payments || [];
    const patientPaymentsTotal = payments.filter((payment)=>payment?.patientPayment?.id).reduce((sum, payment)=>sum.plus(payment.amount), new _decimal.default(0)).toNumber();
    const insurerPaymentsTotal = payments.filter((payment)=>payment?.insurerPayment?.id).reduce((sum, payment)=>sum.plus(payment.amount), new _decimal.default(0)).toNumber();
    const paymentsTotal = payments.reduce((sum, payment)=>sum.plus(payment.amount), new _decimal.default(0)).toNumber();
    const patientPaymentRemainingBalance = new _decimal.default(patientTotal).minus(patientPaymentsTotal).toNumber();
    const insurerPaymentRemainingBalance = new _decimal.default(insuranceCoverageTotal).minus(insurerPaymentsTotal).toNumber();
    return {
        invoiceItemsUndiscountedTotal: invoiceItemsUndiscountedTotal.toNumber(),
        invoiceItemsTotal: invoiceItemsTotal.toNumber(),
        insuranceCoverageTotal: insuranceCoverageTotal.toNumber(),
        patientTotal: patientTotal.toNumber(),
        discountTotal: discountTotal,
        itemAdjustmentsTotal: itemAdjustmentsTotal.toNumber(),
        patientSubtotal: patientSubtotal.toNumber(),
        patientPaymentsTotal,
        insurerPaymentsTotal,
        paymentsTotal,
        patientPaymentRemainingBalance,
        insurerPaymentRemainingBalance
    };
};

//# sourceMappingURL=invoice.js.map