-- liquibase formatted sql

-- changeset cyril:update_inventory_lot_line_trigger_after_insert splitStatements:false

create definer = current_user trigger `inventory_lot_line_AFTER_insert`
    after insert
    on `inventory_lot_line`
    for each row
begin
    declare inventoryId int default -1;

    -- Global Error handling
    declare error_msg TEXT default null;
    declare continue handler for sqlexception, sqlwarning
        begin
            get diagnostics condition 1 error_msg = message_text;
            set error_msg = coalesce(error_msg, 'Unknown error occurred');
            -- Log the error (specific step logging is handled in each block)
        end;

    -- Set inventory id
    select coalesce(
                   (select i.id
                    from `inventory` i
                             left join `inventory_lot` il on i.itemId = il.itemId
                             left join `item_uom` iu on iu.itemId = il.itemId and iu.baseUnit = true
                             left join `stock_in_line` sil on il.stockInLineId = sil.id
                             left join `purchase_order_line` pol on pol.id = sil.purchaseOrderLineId
                    where il.id = new.inventoryLotId
                      and i.uomId = iu.uomId
                    limit 1),
                   -1
           )
    into inventoryId;

    -- Create temp table
    drop temporary table if exists `temp_inventory`;

    create temporary table `temp_inventory`
    (
        onHandQty      decimal(14, 2),
        onHoldQty      decimal(14, 2),
        unavailableQty decimal(14, 2),
        currencyId     int,
        currencyName   varchar(30),
        uomId          int,
        itemId         int,
        price          decimal(14, 2)
    );

    -- Step 1: Insert into temp table
    insert into `temp_inventory` (onHandQty, onHoldQty, unavailableQty, currencyId, currencyName, uomId, itemId, price)
    select coalesce(new.inQty, 0) - coalesce(new.outQty, 0) AS onHandQty,
           coalesce(new.holdQty, 0)                         AS onHoldQty,
           IF(
                   new.status = 'unavailable',
                   coalesce(new.inQty, 0) - coalesce(new.outQty, 0) - coalesce(new.holdQty, 0),
                   0
           )                                                AS unavailableQty,
           c.id                                             AS currencyId,
           coalesce(c.name, 'HKD')                          AS currencyName,
           iu.uomId                                         AS uomId,
           il.itemId                                        AS itemId,
           coalesce(pql.price, 0)                           AS price
    from `inventory_lot` il
             left join `item_uom` iu on iu.itemId = il.itemId and iu.baseUnit = true
             left join `stock_in_line` sil on sil.id = il.stockInLineId
             left join `stock_in` si on si.id = sil.stockInId
             left join `purchase_order_line` pol on pol.id = sil.purchaseOrderLineId
             left join `purchase_order` po on po.id = pol.purchaseOrderId
             left join `purchase_quotation_line` pql on pql.itemId = il.itemId and pql.uomId = pol.uomId
             left join `purchase_quotation` pq on pq.id = pql.purchaseQuotationId
             left join `currency` c on c.id = pq.currencyId
    where il.id = new.inventoryLotId;

    -- Step 2: Insert / Update inventory table
    begin
        declare inventoryErrorMsg text default null;
        declare continue handler for sqlexception, sqlwarning
            begin
                get diagnostics condition 1 inventoryErrorMsg = message_text;
                set inventoryErrorMsg = coalesce(inventoryErrorMsg, 'Unknown error occurred');
            end;

        if inventoryId < 0 then
            insert into `inventory` (itemId, onHandQty, onHoldQty, unavailableQty, price, currencyId, cpu, cpuUnit, cpm,
                                     cpmUnit, uomId, status)
            select ti.itemId         AS itemId,
                   ti.onHandQty      AS onHandQty,
                   ti.onHoldQty      AS onHoldQty,
                   ti.unavailableQty AS unavailableQty,
                   ti.price          AS price,
                   ti.currencyId     AS currencyId,
                   0                 AS cpu,
                   ti.currencyName   AS cpuUnit,
                   0                 AS cpm,
                   ti.currencyName   AS cpmUnit,
                   ti.uomId          AS uomId,
                   if(coalesce(ti.onHandQty - ti.onHoldQty - ti.unavailableQty, 0) > 0, 'available',
                      'unavailable') AS status
            from `temp_inventory` ti;
        else
            update `inventory` i
                join `temp_inventory` ti on i.itemId = ti.itemId and i.uomId = ti.uomId
            set i.onHandQty      = (i.onHandQty + ti.onHandQty),
                i.onHoldQty      = (i.onHoldQty + ti.onHoldQty),
                i.unavailableQty = (i.unavailableQty + ti.unavailableQty),
                i.price          = ti.price,
                i.currencyId     = ti.currencyId,
                i.cpu            = 0,
                i.cpuUnit        = ti.currencyName,
                i.cpm            = 0,
                i.cpmUnit        = ti.currencyName,
                i.uomId          = ti.uomId,
                i.status         = if(coalesce((i.onHandQty + ti.onHandQty) - (i.onHoldQty + ti.onHoldQty) -
                                               (i.unavailableQty + ti.unavailableQty), 0) > 0, 'available',
                                      'unavailable')
            where i.id = inventoryId;
        end if;

        if inventoryErrorMsg is null then
            insert into `trigger_debug_log` (tableName, triggerName, description, status)
            VALUES ('inventory_lot_line', 'after insert', 'Insert / Update Inventory Table', 'success');
        ELSE
            insert into `trigger_debug_log` (tableName, triggerName, description, errorMessages, status)
            VALUES ('inventory_lot_line', 'after insert', 'Insert / Update Inventory Table', inventoryErrorMsg, 'fail');
        end if;
    end;

    -- Clean up
    drop temporary table if exists `temp_inventory`;

    -- Log unhandled errors
    if error_msg is NOT null then
        insert into `trigger_debug_log` (tableName, triggerName, `description`, errorMessages, `status`)
        VALUES ('inventory_lot_line', 'after insert', 'Unhandled error in trigger', error_msg, 'fail');
    end if;
end;