"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.outboundSerialNumberReport = void 0;
const auth_base_1 = require("@things-factory/auth-base");
const biz_base_1 = require("@things-factory/biz-base");
const utils_1 = require("../../../utils");
exports.outboundSerialNumberReport = {
    async outboundSerialNumberReport(_, params, context) {
        try {
            const { tx } = context.state;
            let bizplaceFilter = { name: '', operator: '', value: '' };
            let userFilter = params.filters.find(data => data.name === 'user');
            let fromDate = params.filters.find(data => data.name === 'fromDate');
            let toDate = params.filters.find(data => data.name === 'toDate');
            let orderNo = params.filters.find(data => data.name === 'orderNo');
            let ref = params.filters.find(data => data.name === 'ref');
            let palletId = params.filters.find(data => data.name === 'palletId');
            let cartonId = params.filters.find(data => data.name === 'cartonId');
            let serialNumber = params.filters.find(data => data.name === 'serialNumber');
            if (userFilter) {
                const user = await tx.getRepository(auth_base_1.User).findOne({
                    where: { id: userFilter.value },
                    relations: ['bizplaces']
                });
                const bizplace = user.bizplaces[0];
                if (!bizplace)
                    throw 'Invalid input';
                bizplaceFilter = { name: 'bizplace', operator: 'eq', value: bizplace.id };
            }
            else {
                bizplaceFilter = params.filters.find(data => data.name === 'bizplace');
            }
            if (!bizplaceFilter || !fromDate || !toDate)
                throw 'Invalid input';
            const bizplace = await tx.getRepository(biz_base_1.Bizplace).findOne({
                id: bizplaceFilter.value
            });
            await (0, utils_1.rawProductsQuery)(tx, params, bizplace);
            let extraQueryFilters = '';
            if (orderNo) {
                extraQueryFilters = `${extraQueryFilters} and order_no like '%${orderNo.value}%' `;
            }
            if (palletId) {
                extraQueryFilters = `${extraQueryFilters} and pallet_id like '%${palletId.value}%' `;
            }
            if (cartonId) {
                extraQueryFilters = `${extraQueryFilters} and carton_id like '%${cartonId.value}%' `;
            }
            if (serialNumber) {
                extraQueryFilters = `${extraQueryFilters} and serial_number like '%${serialNumber.value}%' `;
            }
            let refNoQueryFilter = '';
            if (ref) {
                let refValue = ref.value
                    .toLowerCase()
                    .split(',')
                    .map(ref => {
                    return "'%" + ref.trim().replace(/'/g, "''") + "%'";
                })
                    .join(',');
                refNoQueryFilter = `AND (
          Lower(rg.ref_no) LIKE ANY(ARRAY[${refValue}])
          OR Lower(rg.ref_no_2) LIKE ANY(ARRAY[${refValue}])
          OR Lower(rg.ref_no_3) LIKE ANY(ARRAY[${refValue}])
        )`;
            }
            await tx.query(`
        create temp table temp_outbound_serial_number_report on commit drop as (
          select * from (            
            select             
            row_number() over(partition by rg."name" order by coalesce(w.started_at, ii.created_at), p.sku ) as "no",
            rg."name" as "order_no", concat_ws(', ',rg.delivery_address_1,rg.delivery_address_2,rg.delivery_address_3,rg.delivery_address_4,rg.delivery_address_5,rg.postal_code,rg.city,rg.state) as "full_delivery_address",
            rg."attention_to" as "attention_to",
            i.pallet_id, i.carton_id, rg.ref_no, rg.ref_no_2, rg.ref_no_3,
            p.id as "product_id", p.sku as "product_sku", p.brand_sku as "product_brand_sku",
            p.name as "product_name", p.description as "product_description", p."type" as "product_type",
            coalesce(pd.volume, '0') as "product_volume", 
            ii.serial_number, 
            coalesce(w.started_at,ii.created_at) as "etd"
            from inventory_items ii 
            inner join inventories i on i.id = ii.inventory_id 
            inner join temp_products p on p.id = i.product_id
            left join product_details pd on pd.product_id = p.id and pd.packing_type = i.packing_type and pd.packing_size = i.packing_size 
            inner join release_goods rg on rg.id = ii.outbound_order_id::uuid
            left join worksheets w on w.release_good_id = rg.id and w.type = 'PICKING'
            where 
            i.domain_id = $1 and i.bizplace_id = $2
            and coalesce(w.started_at, ii.created_at) between $3 and $4
            ${refNoQueryFilter}
            order by coalesce(w.started_at, ii.created_at), p.sku
          ) src
          where 1=1
          ${extraQueryFilters}
        )
      `, [context.state.domain.id, bizplace.id, fromDate.value, toDate.value]);
            const total = await tx.query(`
        select count(*) from temp_outbound_serial_number_report
      `);
            const result = await tx.query(`
        select *
        from temp_outbound_serial_number_report
        offset $1 limit $2
      `, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]);
            let items = result.map(itm => {
                let data = {
                    no: itm.no,
                    bizplace: {
                        description: bizplace.description,
                        name: bizplace.name
                    },
                    fullDeliveryAddress: itm.full_delivery_address,
                    attentionTo: itm.attention_to,
                    palletId: itm.pallet_id,
                    cartonId: itm.carton_id,
                    orderNo: itm.order_no,
                    refNo1: itm.ref_no,
                    refNo2: itm.ref_no_2,
                    refNo3: itm.ref_no_3,
                    product: {
                        id: itm.product_id,
                        sku: itm.product_sku,
                        brandSku: itm.product_brand_sku,
                        name: itm.product_name,
                        description: itm.product_description,
                        type: itm.product_type,
                        volume: itm.product_volume
                    },
                    serialNumber: itm.serial_number,
                    etd: itm.etd
                };
                return data;
            });
            return {
                items,
                total: total[0].count
            };
        }
        catch (error) {
            throw error;
        }
    }
};
//# sourceMappingURL=outbound-serial-number-report.js.map