"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nonLoadedOrderInventoriesReport = void 0;
const typeorm_1 = require("typeorm");
const product_base_1 = require("@things-factory/product-base");
const sales_base_1 = require("@things-factory/sales-base");
const shell_1 = require("@things-factory/shell");
const worksheet_base_1 = require("@things-factory/worksheet-base");
exports.nonLoadedOrderInventoriesReport = {
    async nonLoadedOrderInventories(_, params, context) {
        const { domain } = context.state;
        try {
            const productFilter = params.filters.find(x => x.name == 'productInfo');
            const roNoFilter = params.filters.find(x => x.name == 'roNo');
            const refNoFilter = params.filters.find(x => x.name == 'refNo');
            const binLocationFilter = params.filters.find(x => x.name == 'binLocation');
            const lotIdFilter = params.filters.find(x => x.name == 'palletId');
            const cartonIdFilter = params.filters.find(x => x.name == 'cartonId');
            const createdAtFilter = params.filters.find(x => x.name == 'createdAt');
            const timezoneOffset = params.filters.find(x => x.name === 'timezoneOffset').value + ' minutes';
            params.filters = params.filters.filter(filter => ['productInfo', 'roNo', 'refNo', 'binLocation', 'palletId', 'cartonId', 'createdAt', 'timezoneOffset'].indexOf(filter.name) ==
                -1);
            const qb = (0, typeorm_1.getRepository)(sales_base_1.OrderInventory).createQueryBuilder('oi');
            (0, shell_1.buildQuery)(qb, params, context);
            qb.select('oi')
                .addSelect('(oi.release_uom_value / oi.release_qty) * oi.picked_qty', 'picked_uom_value')
                .innerJoinAndSelect('oi.inventory', 'inv')
                .innerJoinAndSelect('oi.releaseGood', 'rg')
                .innerJoinAndSelect('rg.bizplace', 'bz')
                .innerJoinAndSelect('oi.product', 'product')
                .leftJoinAndSelect('oi.binLocation', 'bin_loc')
                .innerJoinAndMapMany('w.worksheetDetails', worksheet_base_1.WorksheetDetail, 'wd', 'wd.targetInventory = oi.id')
                .innerJoinAndMapMany('oi.releaseGood', worksheet_base_1.Worksheet, 'w', 'w.id = wd.worksheet')
                .andWhere('rg.status IN (:...releaseGoodStatus)', {
                releaseGoodStatus: [sales_base_1.ORDER_STATUS.PICKING, sales_base_1.ORDER_STATUS.LOADING]
            })
                .andWhere('oi.status IN (:...orderInventoryStatus)', {
                orderInventoryStatus: [
                    sales_base_1.ORDER_INVENTORY_STATUS.PICKED,
                    sales_base_1.ORDER_INVENTORY_STATUS.LOADING,
                    sales_base_1.ORDER_INVENTORY_STATUS.LOADED
                ]
            })
                .andWhere('wd.type = :worksheetDetailType AND wd.status = :worksheetDetailStatus', {
                worksheetDetailType: worksheet_base_1.WORKSHEET_TYPE.LOADING,
                worksheetDetailStatus: worksheet_base_1.WORKSHEET_STATUS.EXECUTING
            })
                .andWhere('oi.domain = :domain', { domain: domain.id });
            if (productFilter) {
                let productFilterValue = `%${productFilter.value.toLowerCase()}%`;
                qb.andWhere(qb => {
                    const subQuery = qb
                        .subQuery()
                        .select()
                        .from(product_base_1.Product, `products`)
                        .where(`products.id = oi.product_id`)
                        .andWhere(new typeorm_1.Brackets(qb => {
                        qb.where('Lower(products.sku) LIKE :productInfo', { productInfo: productFilterValue })
                            .orWhere('Lower(products.name) LIKE :productInfo', { productInfo: productFilterValue })
                            .orWhere('Lower(products.description) LIKE :productInfo', { productInfo: productFilterValue })
                            .orWhere('Lower(products.brand) LIKE :productInfo', { productInfo: productFilterValue });
                    }))
                        .getQuery();
                    return `EXISTS ${subQuery}`;
                });
            }
            if (roNoFilter) {
                qb.andWhere('Lower(rg.name) LIKE :roNo', { roNo: roNoFilter.value.toLowerCase() });
            }
            if (refNoFilter) {
                qb.andWhere('Lower(rg.ref_no) LIKE :refNo', { refNo: refNoFilter.value.toLowerCase() });
            }
            if (binLocationFilter) {
                qb.andWhere('Lower(bin_loc.name) LIKE :binLocation', { binLocation: binLocationFilter.value.toLowerCase() });
            }
            if (lotIdFilter) {
                qb.andWhere('Lower(inv.pallet_id) LIKE :palletId', { palletId: lotIdFilter.value.toLowerCase() });
            }
            if (cartonIdFilter) {
                qb.andWhere('Lower(inv.carton_id) LIKE :cartonId', { cartonId: cartonIdFilter.value.toLowerCase() });
            }
            if (createdAtFilter) {
                qb.andWhere('DATE(wd.created_at) <= :createdAt', { createdAt: createdAtFilter.value });
            }
            qb.groupBy('oi.id')
                .addGroupBy('inv.id')
                .addGroupBy('rg.id')
                .addGroupBy('bz.id')
                .addGroupBy('product.id')
                .addGroupBy('bin_loc.id')
                .addGroupBy('w.id')
                .addGroupBy('wd.id');
            qb.orderBy('rg.name');
            const items = await qb
                .offset((params.pagination.page - 1) * params.pagination.limit)
                .limit(params.pagination.limit)
                .getRawMany();
            const total = await qb.getCount();
            return {
                total,
                items: items.reduce((acc, item) => {
                    acc.push(Object.assign(new sales_base_1.OrderInventory(), {
                        id: item.oi_id,
                        batchId: item.oi_batch_id,
                        packingType: item.oi_packing_type,
                        packingSize: item.oi_packing_size,
                        uom: item.oi_uom,
                        pickedQty: item.oi_picked_qty,
                        pickedUomValue: item.picked_uom_value,
                        product: new product_base_1.Product(item),
                        binLocation: {
                            id: item.bin_loc_id,
                            name: item.bin_loc_name,
                            description: item.bin_loc_description
                        },
                        releaseGood: {
                            id: item.rg_id,
                            name: item.rg_name,
                            refNo: item.rg_ref_no,
                            description: item.rg_description,
                            bizplace: {
                                id: item.bz_id,
                                name: item.bz_name
                            }
                        },
                        inventory: {
                            id: item.inv_id,
                            palletId: item.inv_pallet_id,
                            cartonId: item.inv_carton_id
                        },
                        createdAt: item.wd_created_at,
                        updatedAt: item.oi_updated_at
                    }));
                    return acc;
                }, [])
            };
        }
        catch (error) {
            throw error;
        }
    }
};
//# sourceMappingURL=non-loaded-inventory-report.js.map