"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.zonePicking = void 0;
const typeorm_1 = require("typeorm");
const worksheet_base_1 = require("@things-factory/worksheet-base");
const sales_base_1 = require("@things-factory/sales-base");
const warehouse_base_1 = require("@things-factory/warehouse-base");
const product_base_1 = require("@things-factory/product-base");
const setting_base_1 = require("@things-factory/setting-base");
const uuid_1 = require("uuid");
exports.zonePicking = {
    async scanProductZonePicking(_, { worksheetId, cartonId, productBarcode, binNo, pickingQty }, context) {
        const { domain, tx, user } = context.state;
        try {
            console.time('ws');
            //fetch ws, wsd, oi
            const worksheet = await tx
                .getRepository(worksheet_base_1.Worksheet)
                .createQueryBuilder('ws')
                .innerJoinAndSelect('ws.worksheetDetails', 'wsd', 'wsd.worksheet_id = ws.id')
                .innerJoinAndSelect('wsd.targetInventory', 'oi', 'oi.id= wsd.target_inventory_id')
                .where('ws.id = :worksheetId', { worksheetId: worksheetId })
                .andWhere('ws.domain_id = :domainId', { domainId: domain.id })
                .andWhere('ws.status in (:...status)', {
                status: [worksheet_base_1.WORKSHEET_STATUS.EXECUTING, worksheet_base_1.WORKSHEET_STATUS.PARTIAL_EXECUTING]
            })
                .andWhere('ws.type = :type', { type: worksheet_base_1.WORKSHEET_TYPE.ZONE_PICKING })
                .getOne();
            if (!worksheet)
                throw new Error('No worksheet found');
            let worksheetDetails = worksheet.worksheetDetails;
            let oiIds = worksheetDetails.map(wsd => wsd.targetInventory.id);
            // Use pessimistic lock to prevent race conditions with concurrent requests
            const targetInventories = await tx
                .getRepository(sales_base_1.OrderInventory)
                .createQueryBuilder('oi')
                .setLock('pessimistic_write')
                .innerJoinAndSelect('oi.inventory', 'i', 'i.id = oi.inventory_id')
                .where('oi.id IN(:...oiIds)', { oiIds: oiIds })
                .andWhere('i.carton_id = :cartonId', { cartonId: cartonId })
                .andWhere('oi.status = :status', { status: sales_base_1.ORDER_INVENTORY_STATUS.PROCESSING })
                .orderBy('oi.created_at')
                .getMany();
            if (!targetInventories || targetInventories.length === 0) {
                throw new Error(`No inventory found for carton ID: ${cartonId}. Please verify the carton ID and worksheet details.`);
            }
            //fetch product, product detail
            const productDetail = await tx
                .getRepository(product_base_1.ProductDetail)
                .createQueryBuilder('pd')
                .innerJoinAndSelect('pd.product', 'p')
                .innerJoin('pd.productBarcodes', 'pb')
                .where('pd.id IN (:...productDetailIds)', { productDetailIds: targetInventories.map(oi => oi.productDetailId) })
                .andWhere('p.id IN (:...productIds)', { productIds: targetInventories.map(oi => oi.productId) })
                .andWhere('pb.gtin = :productBarcode', { productBarcode: productBarcode })
                .getOne();
            if (!productDetail) {
                throw new Error(`Product not found with barcode: ${productBarcode}.`);
            }
            const product = productDetail.product;
            let pickedQty = pickingQty ? pickingQty : 1;
            // Add decimal quantity validation
            if (pickingQty % 1 !== 0 && !product.isInventoryDecimal) {
                throw new Error('Decimal quantities are not allowed for this product');
            }
            //calculate unit picked qty if user scan ctn barcode
            let matchingProduct;
            let wsController = new worksheet_base_1.WorksheetController(tx, domain, user);
            matchingProduct = await wsController.getDirectQty(Object.assign(Object.assign({}, productDetail), { product }), productBarcode, pickedQty);
            if (!matchingProduct)
                throw new Error(wsController.ERROR_MSG.FIND.NO_RESULT(productBarcode));
            pickedQty = matchingProduct.qty;
            const sumOfReleaseQty = targetInventories
                .filter((oi) => oi.productDetailId === productDetail.id)
                .map((oi) => oi.releaseQty)
                .reduce((a, b) => a + b, 0);
            // Calculate total picked quantity including the current picking
            const sumOfPickedQty = targetInventories
                .filter((oi) => oi.productDetailId === productDetail.id)
                .map((oi) => oi.pickedQty)
                .reduce((a, b) => a + b, 0);
            // Add the current picking quantity
            const totalPickedQty = sumOfPickedQty + pickedQty;
            if (totalPickedQty > sumOfReleaseQty)
                throw new Error(wsController.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`));
            let productOrderInventory = targetInventories.filter(oi => oi.productId === product.id && oi.productDetailId === productDetail.id);
            // Track processed OI and inventory IDs to prevent duplicate processing within this transaction
            const processedOiIds = new Set();
            const processedInventoryDeductions = new Map();
            //update all oi
            for (const oi of productOrderInventory) {
                let targetInventory = oi;
                let inventory = targetInventory.inventory;
                const targetReleaseQty = targetInventory.releaseQty;
                const targetPickedQty = targetInventory.pickedQty;
                const releaseGood = targetInventory.releaseGood;
                if (pickedQty <= 0)
                    break;
                // Skip if this OI was already processed in this transaction
                if (processedOiIds.has(targetInventory.id)) {
                    console.warn(`Skipping duplicate OI processing: ${targetInventory.id}`);
                    continue;
                }
                // validation to prevent picking if the inventory is involved in cycle count
                let inventoryCheckItem = await tx.getRepository(sales_base_1.InventoryCheckItem).findOne({
                    where: {
                        domain: domain,
                        inventory: inventory.id,
                        status: (0, typeorm_1.In)([
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.PENDING,
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTING,
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.INSPECTED,
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.NOT_TALLY,
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.MISSING,
                            sales_base_1.INVENTORY_CHECK_ITEM_STATUS.ADDED
                        ])
                    }
                });
                if (inventoryCheckItem) {
                    throw new Error(`Inventory currently involved in an ongoing cycle count. Please complete the cycle count to proceed with picking.`);
                }
                //logic for qty deduction
                if (targetInventory.status === sales_base_1.ORDER_INVENTORY_STATUS.PROCESSING &&
                    targetReleaseQty > targetPickedQty &&
                    pickedQty > 0) {
                    // Re-verify OI status from database to prevent race condition
                    const freshOiStatus = await tx
                        .getRepository(sales_base_1.OrderInventory)
                        .createQueryBuilder('oi')
                        .select('oi.status')
                        .where('oi.id = :id', { id: targetInventory.id })
                        .getRawOne();
                    if ((freshOiStatus === null || freshOiStatus === void 0 ? void 0 : freshOiStatus.oi_status) !== sales_base_1.ORDER_INVENTORY_STATUS.PROCESSING) {
                        console.warn(`OI ${targetInventory.id} status changed to ${freshOiStatus === null || freshOiStatus === void 0 ? void 0 : freshOiStatus.oi_status}, skipping`);
                        continue;
                    }
                    let remainingAssignedQty = pickedQty - (targetReleaseQty - targetPickedQty); // -1, 0, 1
                    const gapQtyRemaining = targetReleaseQty - targetPickedQty; // > 0
                    if (binNo && !(targetInventory === null || targetInventory === void 0 ? void 0 : targetInventory.binLocation)) {
                        const binLocation = await tx.getRepository(warehouse_base_1.Location).findOne({
                            where: { domain: domain, name: binNo, type: warehouse_base_1.LOCATION_TYPE.BIN }
                        });
                        if (!binLocation)
                            throw new Error(wsController.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `invalid bin location id`));
                        targetInventory.binLocation = binLocation;
                    }
                    targetInventory.pickedQty += pickedQty > gapQtyRemaining ? gapQtyRemaining : pickedQty;
                    remainingAssignedQty = remainingAssignedQty < 0 ? 0 : remainingAssignedQty;
                    if (targetInventory.pickedQty == targetReleaseQty) {
                        //update oi and wsd to done if pickedQty matches releaseQty
                        // Account for any previous deductions to this inventory in this transaction
                        const previousDeduction = processedInventoryDeductions.get(inventory.id) || 0;
                        const adjustedInventoryQty = inventory.qty - previousDeduction;
                        const leftQty = adjustedInventoryQty - targetInventory.releaseQty;
                        if (leftQty < 0) {
                            throw new Error(wsController.ERROR_MSG.VALIDITY.CANT_PROCEED_STEP_BY('picking', `quantity can't exceed limitation`));
                        }
                        let releaseGood = await tx.getRepository(sales_base_1.ReleaseGood).findOne({
                            where: { id: targetInventory.releaseGoodId }
                        });
                        //update oi
                        targetInventory.status = sales_base_1.ORDER_INVENTORY_STATUS.PICKED;
                        await updateOrderInventories(tx, targetInventory);
                        // Mark this OI as processed
                        processedOiIds.add(targetInventory.id);
                        //update loading wsd if exist
                        let loadingWorksheetDetail = await tx.getRepository(worksheet_base_1.WorksheetDetail).findOne({
                            where: { type: worksheet_base_1.WORKSHEET_TYPE.LOADING, targetInventory: targetInventory }
                        });
                        if (loadingWorksheetDetail && loadingWorksheetDetail.status == worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED) {
                            await tx
                                .getRepository(worksheet_base_1.WorksheetDetail)
                                .update({ id: loadingWorksheetDetail.id }, { status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING, updatedAt: new Date(), updater: user });
                        }
                        //update inventory with proper decimal handling
                        let updateInvObj = {
                            qty: () => `"qty" - :deductQty::numeric`,
                            lockedQty: () => `GREATEST("locked_qty" - :deductQty::numeric, 0)`,
                            uomValue: () => `"uom_value" - :deductUomValue::numeric`,
                            lockedUomValue: () => `GREATEST("locked_uom_value" - :deductUomValue::numeric, 0)`,
                            updater: user,
                            updatedAt: new Date()
                        };
                        await tx
                            .getRepository(warehouse_base_1.Inventory)
                            .createQueryBuilder()
                            .update(warehouse_base_1.Inventory)
                            .set(updateInvObj)
                            .setParameter('deductQty', targetInventory.releaseQty)
                            .setParameter('deductUomValue', targetInventory.releaseUomValue)
                            .where('id = :id', { id: targetInventory.inventory.id })
                            .returning(['qty'])
                            .execute();
                        // Track the deduction for this inventory
                        processedInventoryDeductions.set(inventory.id, previousDeduction + targetInventory.releaseQty);
                        console.time('inv history');
                        await (0, warehouse_base_1.generateInventoryHistory)(inventory, releaseGood, warehouse_base_1.INVENTORY_TRANSACTION_TYPE.PICKING, -targetInventory.releaseQty, -targetInventory.releaseUomValue, user, tx);
                        console.timeEnd('inv history');
                        if (leftQty === 0) {
                            inventory.status = warehouse_base_1.INVENTORY_STATUS.TERMINATED;
                        }
                        let worksheetDetail = worksheetDetails.find((wsd) => wsd.targetInventory.id === targetInventory.id);
                        await tx.getRepository(worksheet_base_1.WorksheetDetail).update({
                            id: worksheetDetail.id
                        }, {
                            status: worksheet_base_1.WORKSHEET_STATUS.DONE,
                            updater: user,
                            updatedAt: new Date()
                        });
                    }
                    else {
                        //updates oi if pickedQty != releaseQty
                        await updateOrderInventories(tx, targetInventory);
                        // Mark this OI as processed even for partial picks
                        processedOiIds.add(targetInventory.id);
                    }
                    //deduct pickedQty for the next oi
                    pickedQty = pickedQty - (targetReleaseQty - targetPickedQty);
                }
            }
            console.timeEnd('ws');
            return true;
        }
        catch (e) {
            throw new Error(e);
        }
    },
    async completeZonePicking(_, { worksheetId }, context) {
        return completeZonePicking(worksheetId, context, false);
    },
    async completeZonePickingPartially(_, { worksheetId }, context) {
        return completeZonePicking(worksheetId, context, true);
    }
};
async function updateOrderInventories(tx, orderInventory) {
    //delete relations
    delete orderInventory.domainId;
    delete orderInventory.bizplaceId;
    delete orderInventory.creatorId;
    delete orderInventory.inventoryCheckId;
    delete orderInventory.inventoryId;
    delete orderInventory.orderProductId;
    delete orderInventory.productId;
    delete orderInventory.releaseGoodId;
    delete orderInventory.replenishmentId;
    delete orderInventory.arrivalNoticeId;
    delete orderInventory.binLocationId;
    delete orderInventory.deliveryOrderId;
    delete orderInventory.originLocationId;
    delete orderInventory.refWorksheetId;
    delete orderInventory.returnOrderId;
    delete orderInventory.transferOrderId;
    delete orderInventory.updaterId;
    delete orderInventory.inspectedLocationId;
    delete orderInventory.productDetailId;
    await tx.getRepository(sales_base_1.OrderInventory).update({ id: orderInventory.id }, orderInventory);
}
async function completeZonePicking(worksheetId, context, isPartial) {
    const { domain, tx, user } = context.state;
    //fetch zone picking worksheet
    const worksheet = await tx.getRepository(worksheet_base_1.Worksheet).findOne({
        where: { id: worksheetId },
        relations: ['worksheetDetails', 'worksheetDetails.targetInventory']
    });
    const worksheetDetails = worksheet.worksheetDetails;
    const targetInventories = worksheetDetails
        // .filter(wsd => wsd.status != 'MISSING' || wsd.status != 'CANCELLED')
        .map((wsd) => wsd.targetInventory);
    let roIds = [...new Set(targetInventories.map(oi => oi.releaseGoodId))];
    //update ro status to partial processing for partial complete
    if (isPartial) {
        await tx.getRepository(sales_base_1.ReleaseGood).update({ id: (0, typeorm_1.In)(roIds), status: sales_base_1.ORDER_STATUS.PROCESSING }, {
            status: sales_base_1.ORDER_STATUS.PARTIAL_PROCESSING,
            updater: user,
            updatedAt: new Date()
        });
    }
    else if (!isPartial) {
        // When completing fully, check if all OrderInventories for each ReleaseGood are actually completed
        // Only update from PARTIAL_PROCESSING to PROCESSING if all OrderInventories are completed
        const releaseGoods = await tx.getRepository(sales_base_1.ReleaseGood).find({
            where: { id: (0, typeorm_1.In)(roIds) },
            relations: ['orderInventories']
        });
        const completedRoIds = [];
        const incompleteRoIds = [];
        for (const rg of releaseGoods) {
            // Check if all OrderInventories are in a completed state (not PROCESSING)
            const completedStatuses = [
                sales_base_1.ORDER_INVENTORY_STATUS.PICKED,
                sales_base_1.ORDER_INVENTORY_STATUS.SORTING,
                sales_base_1.ORDER_INVENTORY_STATUS.LOADING,
                sales_base_1.ORDER_INVENTORY_STATUS.LOADED,
                sales_base_1.ORDER_INVENTORY_STATUS.TERMINATED,
                sales_base_1.ORDER_INVENTORY_STATUS.MISSING,
                sales_base_1.ORDER_INVENTORY_STATUS.CANCELLED
            ];
            const allCompleted = rg.orderInventories.every(oi => completedStatuses.includes(oi.status));
            if (allCompleted) {
                completedRoIds.push(rg.id);
            }
            else {
                incompleteRoIds.push(rg.id);
            }
        }
        // Update ReleaseGoods that are fully completed from PARTIAL_PROCESSING to PROCESSING
        if (completedRoIds.length > 0) {
            await tx.getRepository(sales_base_1.ReleaseGood).update({ id: (0, typeorm_1.In)(completedRoIds), status: sales_base_1.ORDER_STATUS.PARTIAL_PROCESSING }, {
                status: sales_base_1.ORDER_STATUS.PROCESSING,
                updater: user,
                updatedAt: new Date()
            });
        }
        // For ReleaseGoods that still have incomplete OrderInventories:
        // - If they're in PROCESSING, update to PARTIAL_PROCESSING
        // - If they're already in PARTIAL_PROCESSING, leave them as is
        if (incompleteRoIds.length > 0) {
            await tx.getRepository(sales_base_1.ReleaseGood).update({ id: (0, typeorm_1.In)(incompleteRoIds), status: sales_base_1.ORDER_STATUS.PROCESSING }, {
                status: sales_base_1.ORDER_STATUS.PARTIAL_PROCESSING,
                updater: user,
                updatedAt: new Date()
            });
        }
    }
    //find exist loading worksheet
    const existLoadingWorksheet = await tx
        .getRepository(worksheet_base_1.Worksheet)
        .createQueryBuilder('ws')
        .innerJoinAndSelect('ws.releaseGood', 'rg', 'rg.id = ws.release_good_id')
        .where('ws.domain_id = :domainId', { domainId: domain.id })
        .andWhere('ws.type = :type', { type: worksheet_base_1.WORKSHEET_TYPE.LOADING })
        .andWhere('rg.id IN (:...roIds)', { roIds })
        .getMany();
    let roWithoutLoadingWorksheet = roIds.filter(roId => !existLoadingWorksheet.some(ws => ws.releaseGood.id === roId));
    let roWithLoadingWorksheet = roIds.filter(roId => existLoadingWorksheet.some(ws => ws.releaseGood.id === roId));
    // Get disable-QC-in-loading setting
    const disableQcSetting = await tx.getRepository(setting_base_1.Setting).findOne({
        where: {
            domain,
            name: 'disable-QC-in-loading'
        }
    });
    const disableQc = (disableQcSetting === null || disableQcSetting === void 0 ? void 0 : disableQcSetting.value) === 'true';
    if (roWithoutLoadingWorksheet.length > 0) {
        await generateLoadingWorksheets(tx, domain, user, roWithoutLoadingWorksheet, disableQc);
    }
    if (roWithLoadingWorksheet.length > 0) {
        if (disableQc) {
            // When QC is disabled: update PICKED to LOADING status and set sortedQty = pickedQty automatically
            // Use query builder with raw SQL to set sortedQty = pickedQty in a single update
            await tx
                .getRepository(sales_base_1.OrderInventory)
                .createQueryBuilder()
                .update(sales_base_1.OrderInventory)
                .set({
                status: sales_base_1.ORDER_INVENTORY_STATUS.LOADING,
                sortedQty: () => '"picked_qty"',
                updater: user,
                updatedAt: new Date()
            })
                .where('release_good_id IN (:...roIds)', { roIds: roWithLoadingWorksheet })
                .andWhere('status = :status', { status: sales_base_1.ORDER_INVENTORY_STATUS.PICKED })
                .execute();
            const loadingOrderInventories = await tx.getRepository(sales_base_1.OrderInventory).find({
                where: { releaseGood: (0, typeorm_1.In)(roWithLoadingWorksheet), status: sales_base_1.ORDER_INVENTORY_STATUS.LOADING }
            });
            //update loading wsd deactivated to executing
            await tx.getRepository(worksheet_base_1.WorksheetDetail).update({
                targetInventory: (0, typeorm_1.In)(loadingOrderInventories.map(oi => oi.id)),
                type: worksheet_base_1.WORKSHEET_TYPE.LOADING,
                status: worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED
            }, { status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING, updatedAt: new Date(), updater: user });
        }
        else {
            // When QC is enabled: update PICKED to SORTING status (existing behavior)
            await tx.getRepository(sales_base_1.OrderInventory).update({ releaseGood: (0, typeorm_1.In)(roWithLoadingWorksheet), status: sales_base_1.ORDER_INVENTORY_STATUS.PICKED }, {
                status: sales_base_1.ORDER_INVENTORY_STATUS.SORTING,
                updater: user,
                updatedAt: new Date()
            });
            const loadingOrderInventories = await tx.getRepository(sales_base_1.OrderInventory).find({
                where: { releaseGood: (0, typeorm_1.In)(roWithLoadingWorksheet), status: sales_base_1.ORDER_INVENTORY_STATUS.SORTING }
            });
            //update loading wsd deactivated to executing
            await tx.getRepository(worksheet_base_1.WorksheetDetail).update({
                targetInventory: (0, typeorm_1.In)(loadingOrderInventories.map(oi => oi.id)),
                type: worksheet_base_1.WORKSHEET_TYPE.LOADING,
                status: worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED
            }, { status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING, updatedAt: new Date(), updater: user });
        }
    }
    const wsStatus = isPartial ? worksheet_base_1.WORKSHEET_STATUS.PARTIAL_EXECUTING : worksheet_base_1.WORKSHEET_STATUS.DONE;
    await updateWorksheetsAndDetails(tx, worksheet, worksheetDetails, wsStatus, user);
    return true;
}
async function generateLoadingWorksheets(tx, domain, user, roWithoutLoadingWorksheet, disableQc) {
    const releaseGoods = await tx.getRepository(sales_base_1.ReleaseGood).find({
        where: { id: (0, typeorm_1.In)(roWithoutLoadingWorksheet), status: (0, typeorm_1.Not)((0, typeorm_1.In)(sales_base_1.ORDER_STATUS.OBSOLETE)) },
        relations: ['orderInventories', 'sortedBy']
    });
    for (const ro of releaseGoods) {
        const loadingWorksheet = {
            name: `LOAD-` + (0, uuid_1.v4)(),
            type: worksheet_base_1.WORKSHEET_TYPE.LOADING,
            status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING,
            startedAt: new Date(),
            createdAt: new Date(),
            domain: ro.domainId,
            bizplace: ro.bizplaceId,
            releaseGood: ro,
            creator: user,
            sorter: ro.sortedBy ? ro.sortedBy : null
        };
        await tx.getRepository(worksheet_base_1.Worksheet).insert(loadingWorksheet);
        const orderInventories = ro.orderInventories;
        const loadingWorksheetDetails = orderInventories.map(oi => {
            const status = oi.status === sales_base_1.ORDER_INVENTORY_STATUS.PICKED ? worksheet_base_1.WORKSHEET_STATUS.EXECUTING : worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED;
            return {
                name: `LOAD-DETAIL-` + (0, uuid_1.v4)(),
                type: worksheet_base_1.WORKSHEET_TYPE.LOADING,
                status: status,
                createdAt: new Date(),
                domain: domain,
                bizplace: ro.bizplaceId,
                worksheet: loadingWorksheet,
                targetInventory: oi,
                creator: user
            };
        });
        await tx.getRepository(worksheet_base_1.WorksheetDetail).insert(loadingWorksheetDetails);
        // Update picked OrderInventories based on disableQc setting
        if (disableQc) {
            // When QC is disabled: update PICKED to LOADING status and set sortedQty = pickedQty automatically
            await tx
                .getRepository(sales_base_1.OrderInventory)
                .createQueryBuilder()
                .update(sales_base_1.OrderInventory)
                .set({
                status: sales_base_1.ORDER_INVENTORY_STATUS.LOADING,
                sortedQty: () => '"picked_qty"',
                updater: user,
                updatedAt: new Date()
            })
                .where('id IN (:...oiIds)', { oiIds: orderInventories.map(oi => oi.id) })
                .andWhere('status = :status', { status: sales_base_1.ORDER_INVENTORY_STATUS.PICKED })
                .execute();
        }
        else {
            // When QC is enabled: update PICKED to SORTING status (existing behavior)
            await tx.getRepository(sales_base_1.OrderInventory).update({ id: (0, typeorm_1.In)(orderInventories.map(oi => oi.id)), status: sales_base_1.ORDER_INVENTORY_STATUS.PICKED }, {
                status: sales_base_1.ORDER_INVENTORY_STATUS.SORTING,
                updater: user,
                updatedAt: new Date()
            });
        }
    }
}
async function updateWorksheetsAndDetails(tx, worksheet, worksheetDetails, status, updater) {
    worksheet.status = status;
    worksheet.endedAt = status === worksheet_base_1.WORKSHEET_STATUS.DONE ? new Date() : null;
    worksheet.updater = updater;
    worksheet.updatedAt = new Date();
    // Filter only the worksheet details that need to be updated
    const updateWorksheetDetails = worksheetDetails.filter(wsd => { var _a; return ((_a = wsd.targetInventory) === null || _a === void 0 ? void 0 : _a.status) === sales_base_1.ORDER_INVENTORY_STATUS.PICKED; });
    if (updateWorksheetDetails.length > 0) {
        await tx.getRepository(worksheet_base_1.WorksheetDetail).update({ id: (0, typeorm_1.In)(updateWorksheetDetails.map(wsd => wsd.id)) }, {
            status: worksheet_base_1.WORKSHEET_STATUS.DONE,
            updater: updater
        });
    }
    await tx.getRepository(worksheet_base_1.Worksheet).save(worksheet);
}
//# sourceMappingURL=zone-picking.js.map