"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getZonePickingTask = void 0;
const typeorm_1 = require("typeorm");
const auth_base_1 = require("@things-factory/auth-base");
const sales_base_1 = require("@things-factory/sales-base");
const worksheet_base_1 = require("@things-factory/worksheet-base");
const setting_base_1 = require("@things-factory/setting-base");
const zone_worksheet_1 = require("./zone-worksheet");
exports.getZonePickingTask = {
    async getZonePickingTask(_, {}, context) {
        try {
            let worksheet;
            let locationSortingRules;
            await (0, typeorm_1.getConnection)().transaction(async (tx) => {
                const { domain, user } = context.state;
                const assignee = await tx.getRepository(auth_base_1.User).findOne(user.id, { relations: ['domains'] });
                if (((assignee === null || assignee === void 0 ? void 0 : assignee.domains) || []).every((userDomain) => userDomain.id !== domain.id))
                    throw new Error('Target user is not belong to current domain');
                if (!assignee)
                    throw new Error('failed to find target user');
                let worksheetQb = await tx
                    .getRepository(worksheet_base_1.Worksheet)
                    .createQueryBuilder('ws')
                    .select('ws.id')
                    .addSelect('ws.name')
                    .addSelect('ws.status')
                    .where('(ws.domain_id = :domain_id AND ws.type = :type AND ws.assignee_id = :assignee AND (ws.status = :status1 OR ws.status = :status2))', {
                    domain_id: domain.id,
                    type: worksheet_base_1.WORKSHEET_TYPE.ZONE_PICKING,
                    assignee: assignee.id,
                    status1: worksheet_base_1.WORKSHEET_STATUS.EXECUTING,
                    status2: worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED
                });
                worksheet = await worksheetQb.getOne();
                if (!worksheet) {
                    //find a worksheet and update assignee to user
                    let updatedWorksheets = await (0, typeorm_1.getConnection)().transaction(async (tx2) => {
                        let x = await tx2.getRepository(worksheet_base_1.Worksheet).query(`
              UPDATE worksheets ws SET 
                assignee_id = $2,
                updated_at = NOW(),
                updater_id = $2
              FROM (
                SELECT ws.id, ws.name, ws.status, ws.release_good_id FROM worksheets ws
                WHERE ws.domain_id = $1
                AND ws.type = 'ZONE_PICKING'
                AND ws.status IN ('EXECUTING', 'DEACTIVATED')
                AND ws.assignee_id IS NULL
                ORDER BY ws.created_at
              ) src where src.id = ws.id
              RETURNING ws.id;
            `, [domain.id, assignee.id]);
                        return x[0];
                    });
                    if (updatedWorksheets.length == 0)
                        throw new Error('no suitable worksheet found');
                    //fetch updated ws
                    worksheet = await tx
                        .getRepository(worksheet_base_1.Worksheet)
                        .findOne({ where: { id: updatedWorksheets[0].id, assignee: assignee } });
                }
                //validate worksheet is assigned to user
                if (!worksheet)
                    throw new Error('Please try again by clicking the "Get Task" button');
                if (worksheet.status == worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED) {
                    await tx.getRepository(worksheet_base_1.Worksheet).update(worksheet.id, {
                        status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING,
                        startedAt: new Date()
                    });
                    const worksheetDetails = await tx.getRepository(worksheet_base_1.WorksheetDetail).find({
                        where: { worksheet: worksheet },
                        relations: ['targetInventory']
                    });
                    await tx
                        .getRepository(worksheet_base_1.WorksheetDetail)
                        .update({ worksheet: worksheet, status: worksheet_base_1.WORKSHEET_STATUS.DEACTIVATED }, { status: worksheet_base_1.WORKSHEET_STATUS.EXECUTING });
                    const orderInventoryIds = worksheetDetails
                        .map(detail => detail.targetInventory)
                        .filter(oi => oi.status === sales_base_1.ORDER_INVENTORY_STATUS.READY_TO_PICK)
                        .map(oi => oi.id);
                    if (orderInventoryIds.length > 0) {
                        await tx
                            .getRepository(sales_base_1.OrderInventory)
                            .update({ id: (0, typeorm_1.In)(orderInventoryIds) }, { status: sales_base_1.ORDER_INVENTORY_STATUS.PROCESSING });
                        const releaseGoodIds = worksheetDetails
                            .map(detail => detail.targetInventory.releaseGoodId)
                            .filter((value, index, self) => self.indexOf(value) === index);
                        if (releaseGoodIds.length > 0) {
                            await tx
                                .getRepository(sales_base_1.ReleaseGood)
                                .update({ id: (0, typeorm_1.In)(releaseGoodIds), status: sales_base_1.ORDER_STATUS.READY_TO_PICK }, { status: sales_base_1.ORDER_STATUS.PROCESSING });
                        }
                    }
                }
                locationSortingRules = await tx.getRepository(setting_base_1.Setting).findOne({
                    where: { domain, name: 'rule-for-picking-product' }
                });
            });
            //call zonePickingWorksheet
            return zone_worksheet_1.zonePickingWorksheet.zonePickingWorksheet(_, { name: worksheet.name, locationSortingRules, filter: 'PICKING' }, context);
        }
        catch (e) {
            throw e;
        }
    }
};
//# sourceMappingURL=get-zone-picking-task.js.map