"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 afterCreateHook () {
        return afterCreateHook;
    },
    get afterDestroyHook () {
        return afterDestroyHook;
    },
    get afterUpdateHook () {
        return afterUpdateHook;
    },
    get pushNotificationAfterUpdateHook () {
        return pushNotificationAfterUpdateHook;
    },
    get shouldAddLabRequestToInvoice () {
        return shouldAddLabRequestToInvoice;
    }
});
const _constants = require("@tamanu/constants");
const shouldAddLabRequestToInvoice = async (labRequest)=>{
    const encounter = await labRequest.sequelize.models.Encounter.findByPk(labRequest.encounterId);
    if (!encounter) {
        return false;
    }
    const invoicePendingLabRequests = await labRequest.sequelize.models.Setting.get('features.invoicing.invoicePendingLabRequests');
    if (invoicePendingLabRequests && [
        _constants.LAB_REQUEST_STATUSES.SAMPLE_NOT_COLLECTED,
        _constants.LAB_REQUEST_STATUSES.RECEPTION_PENDING
    ].includes(labRequest.status)) {
        return true; // reception_pending and sample-not-collected are auto invoiced if setting is enabled
    }
    return _constants.INVOICEABLE_LAB_REQUEST_STATUSES.includes(labRequest.status);
};
const pushNotificationAfterUpdateHook = async (labRequest, options)=>{
    const shouldPushNotification = [
        _constants.LAB_REQUEST_STATUSES.INTERIM_RESULTS,
        _constants.LAB_REQUEST_STATUSES.PUBLISHED,
        _constants.LAB_REQUEST_STATUSES.INVALIDATED
    ].includes(labRequest.status);
    if (shouldPushNotification && labRequest.status !== labRequest.previous('status')) {
        await labRequest.sequelize.models.Notification.pushNotification(_constants.NOTIFICATION_TYPES.LAB_REQUEST, labRequest.dataValues, {
            transaction: options.transaction
        });
    }
    const shouldDeleteNotification = [
        _constants.LAB_REQUEST_STATUSES.DELETED,
        _constants.LAB_REQUEST_STATUSES.ENTERED_IN_ERROR
    ].includes(labRequest.status);
    if (shouldDeleteNotification && labRequest.status !== labRequest.previous('status')) {
        await labRequest.sequelize.models.Notification.destroy({
            where: {
                metadata: {
                    id: labRequest.id
                }
            },
            transaction: options.transaction
        });
    }
};
const getItemsForLabRequest = async (instance)=>{
    if (instance.labTestPanelRequestId) {
        const labTestPanelRequest = await instance.sequelize.models.LabTestPanelRequest.findByPk(instance.labTestPanelRequestId);
        if (labTestPanelRequest) {
            const panelProduct = await instance.sequelize.models.InvoiceProduct.findOne({
                where: {
                    category: _constants.INVOICE_ITEMS_CATEGORIES.LAB_TEST_PANEL,
                    sourceRecordId: labTestPanelRequest.labTestPanelId
                }
            });
            if (panelProduct) {
                return [
                    {
                        item: labTestPanelRequest,
                        product: panelProduct
                    }
                ];
            }
        }
    }
    const tests = await instance.getTests();
    const testItems = [];
    for (const test of tests){
        const invoiceProduct = await instance.sequelize.models.InvoiceProduct.findOne({
            where: {
                category: _constants.INVOICE_ITEMS_CATEGORIES.LAB_TEST_TYPE,
                sourceRecordId: test.labTestTypeId
            }
        });
        if (invoiceProduct) {
            testItems.push({
                item: test,
                product: invoiceProduct
            });
        }
    }
    return testItems;
};
const addToInvoice = async (instance)=>{
    const encounterId = instance.encounterId;
    if (!encounterId) {
        return; // No encounter for procedure, so no invoice to add to
    }
    const products = await getItemsForLabRequest(instance);
    await Promise.all(products.map(async ({ item, product })=>instance.sequelize.models.Invoice.addItemToInvoice(item, encounterId, product, instance.requestedById)));
};
const removeFromInvoice = async (instance)=>{
    const encounterId = instance.encounterId;
    if (!encounterId) {
        return; // No encounter for procedure, so no invoice to remove from
    }
    const items = await getItemsForLabRequest(instance);
    await Promise.all(items.map(async ({ item })=>instance.sequelize.models.Invoice.removeItemFromInvoice(item, encounterId)));
};
const addOrRemoveFromInvoiceAfterUpdateHook = async (instance)=>{
    if (await shouldAddLabRequestToInvoice(instance)) {
        await addToInvoice(instance);
    } else {
        await removeFromInvoice(instance);
    }
};
const removeFromInvoiceAfterDestroyHook = async (instance)=>{
    await removeFromInvoice(instance);
};
const afterCreateHook = async (instance)=>{
    if (await shouldAddLabRequestToInvoice(instance)) {
        await addToInvoice(instance);
    }
};
const afterUpdateHook = async (labRequest, options)=>{
    await Promise.all([
        pushNotificationAfterUpdateHook(labRequest, options),
        addOrRemoveFromInvoiceAfterUpdateHook(labRequest)
    ]);
};
const afterDestroyHook = async (instance)=>{
    await removeFromInvoiceAfterDestroyHook(instance);
};

//# sourceMappingURL=hooks.js.map