"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get generateReceiptNumber () {
        return generateReceiptNumber;
    },
    get getInsurerPaymentsWithRemainingBalance () {
        return getInsurerPaymentsWithRemainingBalance;
    },
    get getInsurerPaymentsWithRemainingBalanceDisplay () {
        return getInsurerPaymentsWithRemainingBalanceDisplay;
    },
    get getInvoiceInsurerPaymentStatus () {
        return getInvoiceInsurerPaymentStatus;
    },
    get getInvoicePatientPaymentStatus () {
        return getInvoicePatientPaymentStatus;
    },
    get getPatientPaymentsWithRemainingBalance () {
        return getPatientPaymentsWithRemainingBalance;
    },
    get getPatientPaymentsWithRemainingBalanceDisplay () {
        return getPatientPaymentsWithRemainingBalanceDisplay;
    },
    get getSpecificInsurerPaymentRemainingBalance () {
        return getSpecificInsurerPaymentRemainingBalance;
    }
});
const _decimal = /*#__PURE__*/ _interop_require_default(require("decimal.js"));
const _nanoid = require("nanoid");
const _constants = require("@tamanu/constants");
const _invoice = require("./invoice");
const _display = require("./display");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
const RECEIPT_NUMBER_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ123456789';
const RECEIPT_NUMBER_LENGTH = 8;
const generateReceiptNumber = ()=>(0, _nanoid.customAlphabet)(RECEIPT_NUMBER_ALPHABET, RECEIPT_NUMBER_LENGTH)();
const getInvoicePatientPaymentStatus = (paidAmount, owingAmount)=>{
    const roundedPaidAmount = (0, _display.round)(paidAmount, 2);
    const roundedOwingAmount = (0, _display.round)(owingAmount, 2);
    if (roundedPaidAmount < 0) throw new Error('Paid amount cannot be negative');
    if (roundedPaidAmount > roundedOwingAmount) throw new Error('Paid amount cannot be greater than owing amount');
    if (roundedPaidAmount === 0) return _constants.INVOICE_PATIENT_PAYMENT_STATUSES.UNPAID;
    if (roundedPaidAmount === roundedOwingAmount) return _constants.INVOICE_PATIENT_PAYMENT_STATUSES.PAID;
    return _constants.INVOICE_PATIENT_PAYMENT_STATUSES.PARTIAL;
};
const getInvoiceInsurerPaymentStatus = (paidAmount, owingAmount)=>{
    if (paidAmount == null) return _constants.INVOICE_INSURER_PAYMENT_STATUSES.UNPAID;
    const roundedPaidAmount = (0, _display.round)(paidAmount, 2);
    const roundedOwingAmount = (0, _display.round)(owingAmount, 2);
    if (roundedPaidAmount < 0) throw new Error('Paid amount cannot be negative');
    if (roundedPaidAmount > roundedOwingAmount) throw new Error('Paid amount cannot be greater than owing amount');
    if (roundedPaidAmount === 0) return _constants.INVOICE_INSURER_PAYMENT_STATUSES.REJECTED;
    if (roundedPaidAmount === roundedOwingAmount) return _constants.INVOICE_INSURER_PAYMENT_STATUSES.PAID;
    return _constants.INVOICE_INSURER_PAYMENT_STATUSES.PARTIAL;
};
const formatPaymentsWithRemainingBalanceDisplay = (payments)=>{
    return payments.map(({ remainingBalance, ...payment })=>({
            ...payment,
            amount: (0, _display.formatDisplayPrice)(payment.amount),
            remainingBalance: (0, _display.formatDisplayPrice)(remainingBalance)
        }));
};
const getPatientPaymentsWithRemainingBalance = (invoice)=>{
    const payments = invoice.payments || [];
    const patientPayments = payments.filter((payment)=>payment?.patientPayment?.id);
    let { patientTotal } = (0, _invoice.getInvoiceSummary)(invoice);
    return patientPayments.map((payment)=>{
        patientTotal = new _decimal.default(patientTotal).minus(payment.amount).toNumber();
        return {
            ...payment,
            remainingBalance: patientTotal
        };
    });
};
const getPatientPaymentsWithRemainingBalanceDisplay = (invoice)=>{
    return formatPaymentsWithRemainingBalanceDisplay(getPatientPaymentsWithRemainingBalance(invoice));
};
const getInsurerPaymentsWithRemainingBalance = (invoice)=>{
    const payments = invoice.payments || [];
    const insurerPayments = payments.filter((payment)=>payment?.insurerPayment?.id);
    let { insuranceCoverageTotal } = (0, _invoice.getInvoiceSummary)(invoice);
    return insurerPayments?.map((payment)=>{
        insuranceCoverageTotal = new _decimal.default(insuranceCoverageTotal).minus(payment.amount).toNumber();
        return {
            ...payment,
            remainingBalance: insuranceCoverageTotal
        };
    });
};
const getInsurerPaymentsWithRemainingBalanceDisplay = (invoice)=>{
    return formatPaymentsWithRemainingBalanceDisplay(getInsurerPaymentsWithRemainingBalance(invoice));
};
const getSpecificInsurerPaymentRemainingBalance = (insurers, payments, insurerId, total)=>{
    const insurersDiscountPercentage = insurers.filter((insurer)=>insurer.insurerId === insurerId).reduce((sum, insurer)=>sum.plus(insurer?.percentage || 0), new _decimal.default(0)).toNumber();
    const insurerDiscountTotal = new _decimal.default(total).times(insurersDiscountPercentage).toNumber();
    const insurerPaymentsTotal = payments.filter((payment)=>payment?.insurerPayment?.id && payment.insurerPayment.insurerId === insurerId).reduce((sum, payment)=>sum.plus(payment.amount), new _decimal.default(0)).toNumber();
    return {
        insurerDiscountTotal,
        insurerPaymentsTotal,
        insurerPaymentRemainingBalance: new _decimal.default(insurerDiscountTotal).minus(insurerPaymentsTotal).toNumber()
    };
};

//# sourceMappingURL=payments.js.map