[2026-09-05 00:02:41] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 00:13:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 00:23:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 00:33:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 00:42:41] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 00:53:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:02:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:13:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:22:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:33:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:42:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 01:52:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:03:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:13:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:22:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:32:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:43:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 02:53:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:02:50] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:13:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:23:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:32:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:43:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 03:52:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:02:52] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:12:41] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:23:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:32:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:43:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 04:53:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:02:50] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:12:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:22:41] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:32:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:43:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 05:53:01] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:02:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:12:58] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:23:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:32:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:43:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 06:52:50] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:03:00] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:12:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:22:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:32:51] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:42:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 07:52:50] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:02:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:12:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:22:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:32:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:42:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 08:52:53] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:02:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:12:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:22:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:32:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:42:40] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 09:52:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 10:02:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 10:12:59] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 10:22:39] live.INFO: Offline not allowed - triggering cleanup {"user_id":293,"business_id":43} 
[2026-09-05 10:42:38] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:38] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 10:42:38] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 10:42:38] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:42:38] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 10:42:38] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:38] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 10:42:38] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 10:42:38] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 10:42:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-03","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:53] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-03"} 
[2026-09-05 10:42:53] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-03')"} 
[2026-09-05 10:42:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-03') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-03'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:42:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":true,"date":"2026-09-03"} 
[2026-09-05 10:42:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:53] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-04' (includes all types except purchase_order)"} 
[2026-09-05 10:42:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-04'","bindings":["purchase_order",8]} 
[2026-09-05 10:42:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-04"} 
[2026-09-05 10:42:55] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-03","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:55] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-03"} 
[2026-09-05 10:42:55] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-03')"} 
[2026-09-05 10:42:55] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-03') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-03'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:42:55] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":true,"date":"2026-09-03"} 
[2026-09-05 10:42:55] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:55] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-04' (includes all types except purchase_order)"} 
[2026-09-05 10:42:55] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-04'","bindings":["purchase_order",8]} 
[2026-09-05 10:42:55] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-04"} 
[2026-09-05 10:42:58] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-08-06","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:58] live.INFO: Opening stock calculation - including all transactions {"date":"2026-08-06"} 
[2026-09-05 10:42:58] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-08-06')"} 
[2026-09-05 10:42:58] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-08-06') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-08-06'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:42:58] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"61431174.48800000","is_opening":true,"date":"2026-08-06"} 
[2026-09-05 10:42:58] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:42:58] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 10:42:58] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 10:42:58] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 10:43:01] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-08-06","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:43:01] live.INFO: Opening stock calculation - including all transactions {"date":"2026-08-06"} 
[2026-09-05 10:43:01] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-08-06')"} 
[2026-09-05 10:43:01] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-08-06') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-08-06'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:43:01] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"61431174.48800000","is_opening":true,"date":"2026-08-06"} 
[2026-09-05 10:43:01] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:43:01] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 10:43:01] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 10:43:01] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 10:44:58] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 10:45:09] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:45:09] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 10:45:09] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 10:45:09] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 10:45:09] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 10:45:09] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 10:45:09] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 10:45:09] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 10:45:09] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147624925.83960000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 10:45:21] live.INFO: filterProduct method called {"business_id":8,"search_term":"ext","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 10:45:21] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 10:45:21] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 10:45:21] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 10:45:21] live.DEBUG: Applying search filters {"search_term":"ext","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 10:45:21] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 10:45:21] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 10:45:21] live.DEBUG: Added lot number fields to select  
[2026-09-05 10:45:21] live.INFO: filterProduct completed successfully {"result_count":4,"business_id":8,"search_term":"ext"} 
[2026-09-05 10:45:22] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 10:45:24] live.INFO: Product Row Debug - RELOADED {"product_id":272,"product_name":"Tronic 8 port ext","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":1000.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"1":{"unit_id":1,"unit_name":"Pc","unit_price":110.0,"multiplier":1,"has_price":true},"64":{"unit_id":64,"unit_name":"CTN","unit_price":11000.0,"multiplier":"4.0000","has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 10:45:25] live.INFO: Fetching tax rate for product ID: 272  
[2026-09-05 10:45:25] live.INFO: Product ID 272 has no tax assigned.  
[2026-09-05 10:45:28] live.INFO: Fetching tax rate for product ID: 272  
[2026-09-05 10:45:28] live.INFO: Product ID 272 has no tax assigned.  
[2026-09-05 10:46:25] live.INFO: Digitax upload skipped: No tax number provided {"contact_id":873,"contact_name":"","contact_type":"supplier"} 
[2026-09-05 10:46:51] live.INFO: Digitax upload skipped: No tax number provided {"contact_id":874,"contact_name":"","contact_type":"customer"} 
[2026-09-05 10:49:46] live.INFO: === About to call saveProductNewUnitRelationships === {"product_id":338,"request_units":[{"actual_name":"Bag","unit_id":"250","short_name":"bg","relation_unit_id":null,"relation_qty":"1","price":"740"}],"page_batch_id":"20260905_104721_7289"} 
[2026-09-05 10:49:46] live.INFO: === saveProductNewUnitRelationships START === {"product_id":338,"product_name":"Simba Cement 50Kg Bag"} 
[2026-09-05 10:49:46] live.INFO: Units data received {"units_data":[{"actual_name":"Bag","unit_id":"250","short_name":"bg","relation_unit_id":null,"relation_qty":"1","price":"740"}],"count":1} 
[2026-09-05 10:49:46] live.INFO: Processing unit index: 0 {"unit_data":{"actual_name":"Bag","unit_id":"250","short_name":"bg","relation_unit_id":null,"relation_qty":"1","price":"740"}} 
[2026-09-05 10:49:46] live.INFO: Unit found by ID {"unit_id":250,"actual_name":"Bag"} 
[2026-09-05 10:49:46] live.INFO: Unit lookup result {"found":"yes","unit_id":250,"method":"by_id"} 
[2026-09-05 10:49:46] live.INFO: Updating existing unit {"unit_id":250} 
[2026-09-05 10:49:46] live.INFO: Updated unit_price {"new_price":740.0} 
[2026-09-05 10:49:46] live.INFO: Unit updated successfully  
[2026-09-05 10:49:46] live.INFO: Setting as BASE unit {"unit_id":250} 
[2026-09-05 10:49:46] live.INFO: Base unit saved {"base_unit_id":250} 
[2026-09-05 10:49:46] live.INFO: First pass complete {"created_units_count":1,"base_unit_id":250} 
[2026-09-05 10:49:46] live.INFO: === SECOND PASS: Setting relations first ===  
[2026-09-05 10:49:46] live.INFO: === SECOND PASS: Calculating cumulative multipliers ===  
[2026-09-05 10:49:46] live.INFO: === saveProductNewUnitRelationships END ===  
[2026-09-05 10:49:46] live.INFO: OpeningStockController::add - Location Data {"product_id":"338","business_id":8,"locations":{"Illuminate\\Support\\Collection":{"9":"BQT GENERAL BUSINESS (BL0001)","10":"BQT BRANCH 1 (BL0002)","12":"BQT BRANCH 2 (BL0003)","14":"BQT BRANCH 3 (BL0004)"}},"available_locations":[9]} 
[2026-09-05 10:49:46] live.INFO: OpeningStockController::add - Serial Numbers Check {"product_id":"338","business_id":8,"has_serial_numbers":{"9":false},"total_locations_with_serial":0} 
[2026-09-05 10:55:58] live.INFO: === About to call saveProductNewUnitRelationships === {"product_id":339,"request_units":[{"actual_name":"Pc","unit_id":"251","short_name":"Pc","relation_unit_id":null,"relation_qty":"1","price":"10"},{"actual_name":"Pkt","unit_id":"253","short_name":"pkt","relation_unit_id":"251","relation_qty":"56","price":"265"}],"page_batch_id":"20260905_105112_8704"} 
[2026-09-05 10:55:58] live.INFO: === saveProductNewUnitRelationships START === {"product_id":339,"product_name":"Nails 10 inche"} 
[2026-09-05 10:55:58] live.INFO: Units data received {"units_data":[{"actual_name":"Pc","unit_id":"251","short_name":"Pc","relation_unit_id":null,"relation_qty":"1","price":"10"},{"actual_name":"Pkt","unit_id":"253","short_name":"pkt","relation_unit_id":"251","relation_qty":"56","price":"265"}],"count":2} 
[2026-09-05 10:55:58] live.INFO: Processing unit index: 0 {"unit_data":{"actual_name":"Pc","unit_id":"251","short_name":"Pc","relation_unit_id":null,"relation_qty":"1","price":"10"}} 
[2026-09-05 10:55:58] live.INFO: Unit found by ID {"unit_id":251,"actual_name":"Pc"} 
[2026-09-05 10:55:58] live.INFO: Unit lookup result {"found":"yes","unit_id":251,"method":"by_id"} 
[2026-09-05 10:55:58] live.INFO: Updating existing unit {"unit_id":251} 
[2026-09-05 10:55:58] live.INFO: Updated unit_price {"new_price":10.0} 
[2026-09-05 10:55:58] live.INFO: Unit updated successfully  
[2026-09-05 10:55:58] live.INFO: Setting as BASE unit {"unit_id":251} 
[2026-09-05 10:55:58] live.INFO: Base unit saved {"base_unit_id":251} 
[2026-09-05 10:55:58] live.INFO: Processing unit index: 1 {"unit_data":{"actual_name":"Pkt","unit_id":"253","short_name":"pkt","relation_unit_id":"251","relation_qty":"56","price":"265"}} 
[2026-09-05 10:55:58] live.INFO: Unit found by ID {"unit_id":253,"actual_name":"Pkt"} 
[2026-09-05 10:55:58] live.INFO: Unit lookup result {"found":"yes","unit_id":253,"method":"by_id"} 
[2026-09-05 10:55:58] live.INFO: Updating existing unit {"unit_id":253} 
[2026-09-05 10:55:58] live.INFO: Updated unit_price {"new_price":265.0} 
[2026-09-05 10:55:58] live.INFO: Unit updated successfully  
[2026-09-05 10:55:58] live.INFO: First pass complete {"created_units_count":2,"base_unit_id":251} 
[2026-09-05 10:55:58] live.INFO: === SECOND PASS: Setting relations first ===  
[2026-09-05 10:55:58] live.INFO: Setting relation for unit {"unit_id":253,"unit_name":"Pkt","relation_unit_id":251,"relation_unit_name":"Pc","relation_qty":56.0} 
[2026-09-05 10:55:58] live.INFO: Relation saved to database {"unit_id":253,"rel_unit_id":251,"rel_unit_qty":56.0,"base_unit_id":251} 
[2026-09-05 10:55:58] live.INFO: === SECOND PASS: Calculating cumulative multipliers ===  
[2026-09-05 10:55:58] live.INFO: Calculating cumulative multiplier for unit {"unit_id":253,"unit_name":"Pkt"} 
[2026-09-05 10:55:58] live.INFO: === calculateCumulativeMultiplier START === {"unit_id":253,"business_id":8} 
[2026-09-05 10:55:58] live.INFO: Unit found {"unit_id":253,"unit_name":"Pkt","rel_unit_id":251,"rel_unit_qty":"56.0000","base_unit_id":251} 
[2026-09-05 10:55:58] live.INFO: Starting cumulative multiplier {"initial_multiplier":56.0} 
[2026-09-05 10:55:58] live.INFO: Traversing up chain depth: 0 {"current_unit_id":251} 
[2026-09-05 10:55:58] live.INFO: Parent unit found {"parent_unit_id":251,"parent_unit_name":"Pc","parent_rel_unit_id":null,"parent_rel_unit_qty":"1.0000"} 
[2026-09-05 10:55:58] live.INFO: Reached base unit (no rel_unit_id), stopping  
[2026-09-05 10:55:58] live.INFO: Chain traversal complete {"chain":"Pkt (253) -> Pc (251)","final_cumulative_multiplier":56.0,"depth_traversed":0} 
[2026-09-05 10:55:58] live.INFO: === calculateCumulativeMultiplier END === {"result":56.0} 
[2026-09-05 10:55:58] live.INFO: Cumulative multiplier calculated {"unit_id":253,"unit_name":"Pkt","cumulative_multiplier":56.0} 
[2026-09-05 10:55:58] live.INFO: Unit saved with cumulative multiplier {"unit_id":253,"unit_name":"Pkt","base_unit_multiplier":56.0} 
[2026-09-05 10:55:58] live.INFO: === saveProductNewUnitRelationships END ===  
[2026-09-05 10:55:59] live.INFO: OpeningStockController::add - Location Data {"product_id":"339","business_id":8,"locations":{"Illuminate\\Support\\Collection":{"9":"BQT GENERAL BUSINESS (BL0001)","10":"BQT BRANCH 1 (BL0002)","12":"BQT BRANCH 2 (BL0003)","14":"BQT BRANCH 3 (BL0004)"}},"available_locations":[9]} 
[2026-09-05 10:55:59] live.INFO: OpeningStockController::add - Serial Numbers Check {"product_id":"339","business_id":8,"has_serial_numbers":{"9":false},"total_locations_with_serial":0} 
[2026-09-05 10:57:13] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 10:57:19] live.INFO: filterProduct method called {"business_id":8,"search_term":"ceme","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 10:57:19] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 10:57:19] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 10:57:19] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 10:57:19] live.DEBUG: Applying search filters {"search_term":"ceme","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 10:57:19] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 10:57:19] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 10:57:19] live.DEBUG: Added lot number fields to select  
[2026-09-05 10:57:19] live.INFO: filterProduct completed successfully {"result_count":2,"business_id":8,"search_term":"ceme"} 
[2026-09-05 10:57:31] live.INFO: Product Row Debug - RELOADED {"product_id":338,"product_name":"Simba Cement 50Kg Bag","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":740.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"250":{"unit_id":250,"unit_name":"Bag","unit_price":740.0,"multiplier":1,"has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 10:58:33] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"7400.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 10:58:33] live.DEBUG: Payment Calculation {"final_total":7400.0,"curr_total_payment":7400.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 10:58:33] live.INFO: Credit Limit Check Skipped - Fully Paid {"final_total":7400.0,"curr_total_payment":7400.0} 
[2026-09-05 10:58:33] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 10:58:33] live.INFO: is_mpesa_sale value: true  
[2026-09-05 10:58:33] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":true,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1813} 
[2026-09-05 10:58:33] live.INFO: Journal Entry Case: FULL CASH PAYMENT {"transaction_id":1813,"final_total":7400.0,"amount_paid":7400.0,"balance_due":0} 
[2026-09-05 10:58:33] live.INFO: Journal Entries Inserted Successfully {"transaction_id":1813,"entries":[{"transaction_id":1813,"created_by_id":21,"transaction_number":"TRX-6a9bcba9ef0d92.99154185","payment_detail_id":1295,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 10:58:33","updated_at":"2026-09-05 10:58:33","chart_of_account_id":23,"debit":null,"credit":7400.0},{"transaction_id":1813,"created_by_id":21,"transaction_number":"TRX-6a9bcba9ef0d92.99154185","payment_detail_id":1295,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 10:58:33","updated_at":"2026-09-05 10:58:33","chart_of_account_id":27,"debit":7400.0,"credit":null}]} 
[2026-09-05 10:58:34] live.INFO: ETIMS: Customer details retrieved {"transaction_id":1813,"contact_id":94,"customer_name":"Walk-In Customer","has_tin":false,"has_digitax_id":false} 
[2026-09-05 10:58:34] live.ERROR: ETIMS: Missing item_id for product {"product_id":338} 
[2026-09-05 10:58:34] live.ERROR: ETIMS: No valid items to submit after filtering  
[2026-09-05 10:58:34] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1813  
[2026-09-05 10:59:00] live.INFO: filterProduct method called {"business_id":8,"search_term":"cem","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 10:59:00] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 10:59:00] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 10:59:00] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 10:59:00] live.DEBUG: Applying search filters {"search_term":"cem","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 10:59:00] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 10:59:00] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 10:59:00] live.DEBUG: Added lot number fields to select  
[2026-09-05 10:59:00] live.INFO: filterProduct completed successfully {"result_count":2,"business_id":8,"search_term":"cem"} 
[2026-09-05 10:59:02] live.INFO: Product Row Debug - RELOADED {"product_id":338,"product_name":"Simba Cement 50Kg Bag","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":740.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"250":{"unit_id":250,"unit_name":"Bag","unit_price":740.0,"multiplier":1,"has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 10:59:05] live.INFO: filterProduct method called {"business_id":8,"search_term":"nail","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 10:59:05] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 10:59:05] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 10:59:05] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 10:59:05] live.DEBUG: Applying search filters {"search_term":"nail","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 10:59:05] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 10:59:05] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 10:59:05] live.DEBUG: Added lot number fields to select  
[2026-09-05 10:59:05] live.INFO: filterProduct completed successfully {"result_count":1,"business_id":8,"search_term":"nail"} 
[2026-09-05 10:59:06] live.INFO: Product Row Debug - RELOADED {"product_id":339,"product_name":"Nails 10 inche","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":10.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"251":{"unit_id":251,"unit_name":"Pc","unit_price":10.0,"multiplier":1,"has_price":true},"253":{"unit_id":253,"unit_name":"Pkt","unit_price":265.0,"multiplier":"56.0000","has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 10:59:14] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:14] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:14] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:14] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:15] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:15] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:15] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:15] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:16] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:16] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:16] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:16] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:17] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:17] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:17] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:17] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:18] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:18] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:18] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:18] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:19] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:19] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:19] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:19] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:20] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:20] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:20] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:20] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:21] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:21] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:21] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:21] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:22] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:22] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:22] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:22] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:23] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:23] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:24] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:24] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:24] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:24] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:25] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:25] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:25] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:25] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:26] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:26] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:26] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:26] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:27] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:27] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:27] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:27] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:28] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:28] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:28] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:28] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:29] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:29] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:29] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:29] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:30] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:30] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:30] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:30] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:31] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:31] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:31] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:31] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:32] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:32] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:33] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:33] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:34] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:34] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:34] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:34] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:35] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"4230.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 10:59:35] live.DEBUG: Payment Calculation {"final_total":4230.0,"curr_total_payment":0.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 10:59:35] live.DEBUG: Contact Credit Limit Retrieved {"contact_id":"94","contact_name":"Walk-In Customer","credit_limit":"0.0000"} 
[2026-09-05 10:59:35] live.INFO: Credit Limit Check - Current Transaction Only {"contact_id":"94","contact_name":"Walk-In Customer","credit_limit":"0.0000","final_total":4230.0,"curr_total_payment":0.0,"current_due":4230.0,"will_exceed_limit":true} 
[2026-09-05 10:59:35] live.WARNING: Credit Limit Exceeded for Current Transaction {"contact_id":"94","contact_name":"Walk-In Customer","current_due":4230.0,"credit_limit":"0.0000","exceeded_by":4230.0} 
[2026-09-05 10:59:35] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:35] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:35] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:35] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:36] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:36] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:36] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:36] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:37] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:37] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:37] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:37] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:38] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:38] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:39] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:39] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 10:59:39] live.INFO: Fetching tax rate for product ID: 339  
[2026-09-05 10:59:39] live.INFO: Product ID 339 has no tax assigned.  
[2026-09-05 11:00:03] live.INFO: Credit Limit Check Started {"contact_id":"874","status":"final","final_total":"4230.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 11:00:03] live.DEBUG: Payment Calculation {"final_total":4230.0,"curr_total_payment":0.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 11:00:03] live.INFO: Credit Limit Check Skipped - No Credit Limit Set {"contact_id":"874","contact_name":""} 
[2026-09-05 11:00:03] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 11:00:03] live.INFO: is_mpesa_sale value: true  
[2026-09-05 11:00:03] live.INFO: Journal Entry Case: FULL CREDIT SALE {"transaction_id":1814,"final_total":4230.0,"amount_paid":0.0,"balance_due":4230.0} 
[2026-09-05 11:00:03] live.INFO: Journal Entries Inserted Successfully {"transaction_id":1814,"entries":[{"transaction_id":1814,"created_by_id":21,"transaction_number":"TRX-6a9bcc03d2f141.75434356","payment_detail_id":1296,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:00:03","updated_at":"2026-09-05 11:00:03","chart_of_account_id":23,"debit":null,"credit":4230.0},{"transaction_id":1814,"created_by_id":21,"transaction_number":"TRX-6a9bcc03d2f141.75434356","payment_detail_id":1296,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:00:03","updated_at":"2026-09-05 11:00:03","chart_of_account_id":19,"debit":4230.0,"credit":null}]} 
[2026-09-05 11:00:03] live.INFO: Inserted purchase sell mapping {"count":1,"data":[{"sell_line_id":1160,"purchase_line_id":1573,"quantity":112.0,"created_at":"2026-09-05 11:00:03","updated_at":"2026-09-05 11:00:03"}]} 
[2026-09-05 11:00:03] live.INFO: Inserted COGS → Inventory journal entries {"count":2} 
[2026-09-05 11:00:03] live.INFO: Inserted Retained Earnings (profit) entries {"count":1,"total_profit":3670.0} 
[2026-09-05 11:00:03] live.INFO: ETIMS: Customer details retrieved {"transaction_id":1814,"contact_id":874,"customer_name":"Mutuku LTD","has_tin":false,"has_digitax_id":false} 
[2026-09-05 11:00:03] live.ERROR: ETIMS: Missing item_id for product {"product_id":338} 
[2026-09-05 11:00:03] live.ERROR: ETIMS: Missing item_id for product {"product_id":339} 
[2026-09-05 11:00:03] live.ERROR: ETIMS: No valid items to submit after filtering  
[2026-09-05 11:00:04] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1814  
[2026-09-05 11:01:25] live.INFO: filterProduct method called {"business_id":8,"search_term":"nai","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 11:01:25] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 11:01:25] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 11:01:25] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 11:01:25] live.DEBUG: Applying search filters {"search_term":"nai","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 11:01:25] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 11:01:25] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 11:01:25] live.DEBUG: Added lot number fields to select  
[2026-09-05 11:01:25] live.INFO: filterProduct completed successfully {"result_count":1,"business_id":8,"search_term":"nai"} 
[2026-09-05 11:01:25] live.INFO: Product Row Debug - RELOADED {"product_id":339,"product_name":"Nails 10 inche","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":10.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"251":{"unit_id":251,"unit_name":"Pc","unit_price":10.0,"multiplier":1,"has_price":true},"253":{"unit_id":253,"unit_name":"Pkt","unit_price":265.0,"multiplier":"56.0000","has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 11:01:30] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:01:58] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:01:58] live.INFO: STK Push Request Received. {"request_input":{"phone":"0704592348","amount":"700.00"}} 
[2026-09-05 11:01:58] live.INFO: Phone number formatted. {"formatted_phone":"254704592348"} 
[2026-09-05 11:01:58] live.INFO: Phone and Amount after formatting. {"phone":"254704592348","amount":700} 
[2026-09-05 11:01:58] live.INFO: Timestamp for STK Push: {"timestamp":"20260905110958"} 
[2026-09-05 11:01:58] live.INFO: Transaction type determined. {"transaction_type":"CustomerBuyGoodsOnline"} 
[2026-09-05 11:01:58] live.INFO: PartyB to be used in STK Push. {"type":"till","partyB":5699724,"short_code":"3582003","child_number":"3582003","till_no":5699724} 
[2026-09-05 11:01:58] live.INFO: Callback URLs set. {"callbackURL":"https://now.riset.cloud/api/payment/callback","validationURL":"https://now.riset.cloud/api/payment/validation"} 
[2026-09-05 11:01:58] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:01:58] live.INFO: Generated password for M-Pesa STK Push. {"password":"MzU4MjAwMzhkZjliNGQ4NTViNzdhMjBiZDIyNTdlZTg2ZjJiNDgyYjE4MTYyMzdlMGUyNDhlMzlmZjhjYmQzZTczYWFiZmYyMDI2MDkwNTExMDk1OA=="} 
[2026-09-05 11:01:58] live.INFO: Payload prepared for STK Push. {"payload":{"BusinessShortCode":"3582003","Password":"MzU4MjAwMzhkZjliNGQ4NTViNzdhMjBiZDIyNTdlZTg2ZjJiNDgyYjE4MTYyMzdlMGUyNDhlMzlmZjhjYmQzZTczYWFiZmYyMDI2MDkwNTExMDk1OA==","Timestamp":"20260905110958","TransactionType":"CustomerBuyGoodsOnline","Amount":700,"PartyA":"254704592348","PartyB":5699724,"PhoneNumber":"254704592348","CallBackURL":"https://now.riset.cloud/api/payment/callback","AccountReference":12,"TransactionDesc":"Biz"}} 
[2026-09-05 11:01:58] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:01:59] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:01:59] live.INFO: Registering URLs. {"shortCode":"3582003","confirmationURL":"https://now.riset.cloud/api/payment/callback","validationURL":"https://now.riset.cloud/api/payment/validation"} 
[2026-09-05 11:02:00] live.INFO: URL registration response. {"response":"{
                    \"requestId\":\"c001-45f2-99b6-4894922e6a3e2572702\",
                    \"errorCode\": \"500.003.1001\",
                    \"errorMessage\": \"URLs are already registered\"
                }
            "} 
[2026-09-05 11:02:01] live.INFO: STK Push response received. {"response":{"MerchantRequestID":"b2ef-4261-b21b-1f6a20e4b7dc769093","CheckoutRequestID":"ws_CO_05092026110201160704592348","ResponseCode":"0","ResponseDescription":"Success. Request accepted for processing","CustomerMessage":"Success. Request accepted for processing"}} 
[2026-09-05 11:02:35] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:02:35] live.INFO: STK Push Request Received. {"request_input":{"phone":"0704592348","amount":"700.00"}} 
[2026-09-05 11:02:35] live.INFO: Phone number formatted. {"formatted_phone":"254704592348"} 
[2026-09-05 11:02:35] live.INFO: Phone and Amount after formatting. {"phone":"254704592348","amount":700} 
[2026-09-05 11:02:35] live.INFO: Timestamp for STK Push: {"timestamp":"20260905110935"} 
[2026-09-05 11:02:35] live.INFO: Transaction type determined. {"transaction_type":"CustomerBuyGoodsOnline"} 
[2026-09-05 11:02:35] live.INFO: PartyB to be used in STK Push. {"type":"till","partyB":5699724,"short_code":"3582003","child_number":"3582003","till_no":5699724} 
[2026-09-05 11:02:35] live.INFO: Callback URLs set. {"callbackURL":"https://now.riset.cloud/api/payment/callback","validationURL":"https://now.riset.cloud/api/payment/validation"} 
[2026-09-05 11:02:35] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:02:35] live.INFO: Generated password for M-Pesa STK Push. {"password":"MzU4MjAwMzhkZjliNGQ4NTViNzdhMjBiZDIyNTdlZTg2ZjJiNDgyYjE4MTYyMzdlMGUyNDhlMzlmZjhjYmQzZTczYWFiZmYyMDI2MDkwNTExMDkzNQ=="} 
[2026-09-05 11:02:35] live.INFO: Payload prepared for STK Push. {"payload":{"BusinessShortCode":"3582003","Password":"MzU4MjAwMzhkZjliNGQ4NTViNzdhMjBiZDIyNTdlZTg2ZjJiNDgyYjE4MTYyMzdlMGUyNDhlMzlmZjhjYmQzZTczYWFiZmYyMDI2MDkwNTExMDkzNQ==","Timestamp":"20260905110935","TransactionType":"CustomerBuyGoodsOnline","Amount":700,"PartyA":"254704592348","PartyB":5699724,"PhoneNumber":"254704592348","CallBackURL":"https://now.riset.cloud/api/payment/callback","AccountReference":12,"TransactionDesc":"Biz"}} 
[2026-09-05 11:02:35] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:02:36] live.INFO: Loaded Payment Settings: {"type":"till","short_code":"3582003","child_number":"3582003","till_no":5699724,"passkey":"8df9b4d855b77a20bd2257ee86f2b482b1816237e0e248e39ff8cbd3e73aabff","consumer_key":"W9AyBGwLeBRq0FAkn2FG3g9EJK9fF3nKwGTzG2pNtByd5tnQ","consumer_secret":"nziTooyd6JS0GC08ZG7456Ab531RVYOI1AyeZNXpDKha0xQ6mEvbFtOiAVAjlhyc","site_url":"https://now.riset.cloud/","payment_options":"[\"custom_pay_1\",\"custom_pay_2\"]"} 
[2026-09-05 11:02:36] live.INFO: Registering URLs. {"shortCode":"3582003","confirmationURL":"https://now.riset.cloud/api/payment/callback","validationURL":"https://now.riset.cloud/api/payment/validation"} 
[2026-09-05 11:02:37] live.INFO: URL registration response. {"response":"{
                    \"requestId\":\"ec49-4b64-87ab-0a9cf015b8db2545004\",
                    \"errorCode\": \"500.003.1001\",
                    \"errorMessage\": \"URLs are already registered\"
                }
            "} 
[2026-09-05 11:02:47] live.INFO: STK Push response received. {"response":{"MerchantRequestID":"747f-478e-b460-0507a37ebf7f85","CheckoutRequestID":"ws_CO_05092026110247664704592348","ResponseCode":"0","ResponseDescription":"Success. Request accepted for processing","CustomerMessage":"Success. Request accepted for processing"}} 
[2026-09-05 11:03:14] live.INFO: Credit Limit Check Started {"contact_id":"874","status":"draft","final_total":"700.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 11:03:14] live.INFO: Credit Limit Check Skipped - Draft or Sales Order {"status":"draft","type":"not_set"} 
[2026-09-05 11:03:14] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 11:03:14] live.INFO: is_mpesa_sale value: true  
[2026-09-05 11:03:14] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1815  
[2026-09-05 11:03:54] live.INFO: filterProduct method called {"business_id":8,"search_term":"ceme","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 11:03:54] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 11:03:54] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 11:03:54] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 11:03:54] live.DEBUG: Applying search filters {"search_term":"ceme","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 11:03:54] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 11:03:54] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 11:03:54] live.DEBUG: Added lot number fields to select  
[2026-09-05 11:03:54] live.INFO: filterProduct completed successfully {"result_count":2,"business_id":8,"search_term":"ceme"} 
[2026-09-05 11:03:55] live.INFO: Product Row Debug - RELOADED {"product_id":338,"product_name":"Simba Cement 50Kg Bag","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":740.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"250":{"unit_id":250,"unit_name":"Bag","unit_price":740.0,"multiplier":1,"has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 11:04:25] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"7400.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 11:04:25] live.DEBUG: Payment Calculation {"final_total":7400.0,"curr_total_payment":7400.0,"is_credit_sale":false,"payment_count":2} 
[2026-09-05 11:04:25] live.INFO: Credit Limit Check Skipped - Fully Paid {"final_total":7400.0,"curr_total_payment":7400.0} 
[2026-09-05 11:04:25] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 11:04:25] live.INFO: is_mpesa_sale value: true  
[2026-09-05 11:04:25] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":true,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1816} 
[2026-09-05 11:04:25] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":true,"is_valid_mpesa_sale":false,"payment_method_input":"custom_pay_4","mpesa_transaction_id":null,"transaction_id":1816} 
[2026-09-05 11:04:25] live.INFO: Journal Entry Case: PARTIAL PAYMENT {"transaction_id":1816,"final_total":7400.0,"amount_paid":3000.0,"balance_due":4400.0} 
[2026-09-05 11:04:25] live.INFO: Journal Entries Inserted Successfully {"transaction_id":1816,"entries":[{"transaction_id":1816,"created_by_id":21,"transaction_number":"TRX-6a9bcd0986a2e0.77379118","payment_detail_id":1299,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:04:25","updated_at":"2026-09-05 11:04:25","chart_of_account_id":23,"debit":null,"credit":7400.0},{"transaction_id":1816,"created_by_id":21,"transaction_number":"TRX-6a9bcd0986a2e0.77379118","payment_detail_id":1299,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:04:25","updated_at":"2026-09-05 11:04:25","chart_of_account_id":27,"debit":3000.0,"credit":null},{"transaction_id":1816,"created_by_id":21,"transaction_number":"TRX-6a9bcd0986a2e0.77379118","payment_detail_id":1299,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:04:25","updated_at":"2026-09-05 11:04:25","chart_of_account_id":19,"debit":4400.0,"credit":null}]} 
[2026-09-05 11:04:25] live.INFO: ETIMS: Customer details retrieved {"transaction_id":1816,"contact_id":94,"customer_name":"Walk-In Customer","has_tin":false,"has_digitax_id":false} 
[2026-09-05 11:04:25] live.ERROR: ETIMS: Missing item_id for product {"product_id":338} 
[2026-09-05 11:04:25] live.ERROR: ETIMS: No valid items to submit after filtering  
[2026-09-05 11:04:25] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1816  
[2026-09-05 11:05:06] live.INFO: filterProduct method called {"business_id":8,"search_term":"cem","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 11:05:06] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 11:05:06] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 11:05:06] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 11:05:06] live.DEBUG: Applying search filters {"search_term":"cem","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 11:05:06] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 11:05:06] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 11:05:06] live.DEBUG: Added lot number fields to select  
[2026-09-05 11:05:06] live.INFO: filterProduct completed successfully {"result_count":2,"business_id":8,"search_term":"cem"} 
[2026-09-05 11:05:08] live.INFO: Product Row Debug - RELOADED {"product_id":338,"product_name":"Simba Cement 50Kg Bag","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":740.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"250":{"unit_id":250,"unit_name":"Bag","unit_price":740.0,"multiplier":1,"has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 11:05:18] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"740.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 11:05:18] live.DEBUG: Payment Calculation {"final_total":740.0,"curr_total_payment":740.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 11:05:18] live.INFO: Credit Limit Check Skipped - Fully Paid {"final_total":740.0,"curr_total_payment":740.0} 
[2026-09-05 11:05:18] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 11:05:18] live.INFO: is_mpesa_sale value: true  
[2026-09-05 11:05:18] live.INFO: Journal Entry Case: FULL CASH PAYMENT {"transaction_id":1817,"final_total":740.0,"amount_paid":740.0,"balance_due":0} 
[2026-09-05 11:05:18] live.INFO: Journal Entries Inserted Successfully {"transaction_id":1817,"entries":[{"transaction_id":1817,"created_by_id":21,"transaction_number":"TRX-6a9bcd3ebcf8b0.31877723","payment_detail_id":1300,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:05:18","updated_at":"2026-09-05 11:05:18","chart_of_account_id":23,"debit":null,"credit":740.0},{"transaction_id":1817,"created_by_id":21,"transaction_number":"TRX-6a9bcd3ebcf8b0.31877723","payment_detail_id":1300,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:05:18","updated_at":"2026-09-05 11:05:18","chart_of_account_id":27,"debit":740.0,"credit":null}]} 
[2026-09-05 11:05:30] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"740.00","is_credit_sale":"0","exclude_transaction_id":"1817"} 
[2026-09-05 11:05:30] live.DEBUG: Payment Calculation {"final_total":740.0,"curr_total_payment":740.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 11:05:30] live.INFO: Credit Limit Check Skipped - Fully Paid {"final_total":740.0,"curr_total_payment":740.0} 
[2026-09-05 11:05:30] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":false,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1817} 
[2026-09-05 11:05:30] live.INFO: ETIMS: Customer details retrieved {"transaction_id":1817,"contact_id":94,"customer_name":"Walk-In Customer","has_tin":false,"has_digitax_id":false} 
[2026-09-05 11:05:30] live.ERROR: ETIMS: Missing item_id for product {"product_id":338} 
[2026-09-05 11:05:30] live.ERROR: ETIMS: No valid items to submit after filtering  
[2026-09-05 11:05:30] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1817  
[2026-09-05 11:05:37] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:05:49] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:07:06] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:08:14] live.INFO: Purchases array from request {"purchases":[{"product_id":"338","variation_id":"343","quantity":"90","product_unit_id":"250","sub_unit_id":"250","pp_without_discount":"612.07","discount_percent":"0.00","purchase_price":"612.07","purchase_line_tax_id":"1","item_tax":"97.93","purchase_price_inc_tax":"710.00","profit_percent":"4.23","default_sell_price":"740.00","lot_number":null,"mfg_date":null,"exp_date":null,"imei_numbers":"[]","imei_count":"0"},{"product_id":"339","variation_id":"344","quantity":"800","product_unit_id":"251","sub_unit_id":"253","pp_without_discount":"300","discount_percent":"0.00","purchase_price":"300.00","purchase_line_tax_id":null,"item_tax":"0.00","purchase_price_inc_tax":"300.00","profit_percent":"86.67","default_sell_price":"560.00","lot_number":null,"mfg_date":null,"exp_date":null,"imei_numbers":"[]","imei_count":"0"}],"purchases_json":"[{\"product_id\":\"338\",\"variation_id\":\"343\",\"quantity\":\"90\",\"product_unit_id\":\"250\",\"sub_unit_id\":\"250\",\"pp_without_discount\":\"612.07\",\"discount_percent\":\"0.00\",\"purchase_price\":\"612.07\",\"purchase_line_tax_id\":\"1\",\"item_tax\":\"97.93\",\"purchase_price_inc_tax\":\"710.00\",\"profit_percent\":\"4.23\",\"default_sell_price\":\"740.00\",\"lot_number\":null,\"mfg_date\":null,\"exp_date\":null,\"imei_numbers\":\"[]\",\"imei_count\":\"0\"},{\"product_id\":\"339\",\"variation_id\":\"344\",\"quantity\":\"800\",\"product_unit_id\":\"251\",\"sub_unit_id\":\"253\",\"pp_without_discount\":\"300\",\"discount_percent\":\"0.00\",\"purchase_price\":\"300.00\",\"purchase_line_tax_id\":null,\"item_tax\":\"0.00\",\"purchase_price_inc_tax\":\"300.00\",\"profit_percent\":\"86.67\",\"default_sell_price\":\"560.00\",\"lot_number\":null,\"mfg_date\":null,\"exp_date\":null,\"imei_numbers\":\"[]\",\"imei_count\":\"0\"}]"} 
[2026-09-05 11:08:14] live.WARNING: Digitax stock update skipped: Missing item_id for product_id 338  
[2026-09-05 11:08:14] live.WARNING: Digitax stock update skipped: Missing item_id for product_id 339  
[2026-09-05 11:08:14] live.INFO: Purchase lines created {"transaction_id":1818,"purchase_lines_count":2,"purchase_lines":[{"id":1574,"transaction_id":1818,"product_id":338,"variation_id":343,"quantity":90.0,"secondary_unit_quantity":"0.0000","pp_without_discount":"612.0700","discount_percent":"0.00","purchase_price":"612.0700","purchase_price_inc_tax":"710.0000","item_tax":"97.9300","tax_id":1,"purchase_requisition_line_id":null,"purchase_order_line_id":null,"quantity_sold":"0.0000","quantity_adjusted":"0.0000","quantity_returned":"0.0000","po_quantity_purchased":"0.0000","mfg_quantity_used":"0.0000","mfg_date":null,"exp_date":null,"lot_number":null,"sub_unit_id":null,"created_at":"2026-09-05T08:08:14.000000Z","updated_at":"2026-09-05T08:08:14.000000Z"},{"id":1575,"transaction_id":1818,"product_id":339,"variation_id":344,"quantity":44800.0,"secondary_unit_quantity":"0.0000","pp_without_discount":"5.3571","discount_percent":"0.00","purchase_price":"5.3571","purchase_price_inc_tax":"5.3571","item_tax":"0.0000","tax_id":null,"purchase_requisition_line_id":null,"purchase_order_line_id":null,"quantity_sold":"0.0000","quantity_adjusted":"0.0000","quantity_returned":"0.0000","po_quantity_purchased":"0.0000","mfg_quantity_used":"0.0000","mfg_date":null,"exp_date":null,"lot_number":null,"sub_unit_id":253,"created_at":"2026-09-05T08:08:14.000000Z","updated_at":"2026-09-05T08:08:14.000000Z"}]} 
[2026-09-05 11:08:14] live.INFO: Processing purchase row - 0 {"row_index":0,"product_id":"338","variation_id":"343","quantity":"90","has_imei":true,"imei_raw":"[]","purchase_data_keys":["product_id","variation_id","quantity","product_unit_id","sub_unit_id","pp_without_discount","discount_percent","purchase_price","purchase_line_tax_id","item_tax","purchase_price_inc_tax","profit_percent","default_sell_price","lot_number","mfg_date","exp_date","imei_numbers","imei_count"]} 
[2026-09-05 11:08:14] live.INFO: IMEI Data - Parsed for row 0 {"row_index":0,"imei_count":0,"imei_data":[],"imei_json":"[]"} 
[2026-09-05 11:08:14] live.INFO: IMEI data is empty or invalid for row 0 {"imeiData":[]} 
[2026-09-05 11:08:14] live.INFO: Processing purchase row - 1 {"row_index":1,"product_id":"339","variation_id":"344","quantity":"800","has_imei":true,"imei_raw":"[]","purchase_data_keys":["product_id","variation_id","quantity","product_unit_id","sub_unit_id","pp_without_discount","discount_percent","purchase_price","purchase_line_tax_id","item_tax","purchase_price_inc_tax","profit_percent","default_sell_price","lot_number","mfg_date","exp_date","imei_numbers","imei_count"]} 
[2026-09-05 11:08:14] live.INFO: IMEI Data - Parsed for row 1 {"row_index":1,"imei_count":0,"imei_data":[],"imei_json":"[]"} 
[2026-09-05 11:08:14] live.INFO: IMEI data is empty or invalid for row 1 {"imeiData":[]} 
[2026-09-05 11:08:14] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":false,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1818} 
[2026-09-05 11:08:14] live.INFO: Purchase created successfully with IMEI data {"transaction_id":1818,"ref_no":"PO2026/0192","final_total":303900.0} 
[2026-09-05 11:10:37] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":false,"is_valid_mpesa_sale":false,"payment_method_input":"bank_transfer","mpesa_transaction_id":null,"transaction_id":1819} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:10:53] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:10:53] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:10:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"58905818.27480000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:10:53] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:10:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539708.97360000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:10:53] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:10:53] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:10:53] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:10:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"79322050.00000000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:10:53] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:10:53] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:10:53] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:10:53] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149671803.00000000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:11:54] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":false,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1820} 
[2026-09-05 11:13:08] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:08] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:13:08] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:13:08] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:08] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"58905818.27480000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:13:08] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:08] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:13:08] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:08] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539708.97360000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:13:09] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:09] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:09] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:13:09] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:13:09] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:09] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"79322050.00000000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:13:09] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:09] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:09] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:13:09] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:09] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149671803.00000000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:13:12] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:12] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 11:13:12] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 11:13:12] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:12] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147661370.89360000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 11:13:12] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:12] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:13:12] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:12] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539708.97360000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:13:13] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:13] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:13] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 11:13:13] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 11:13:13] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:13] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149158323.00000000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 11:13:13] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:13] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:13] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:13:13] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:13] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149671803.00000000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:13:21] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:21] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:13:21] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:13:21] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:21] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"58905818.27480000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:13:21] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:13:21] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:13:21] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:21] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539708.97360000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:13:22] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:22] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:22] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:13:22] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:13:22] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:13:22] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"79322050.00000000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:13:22] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":true,"filters":"all","permitted_locations":null} 
[2026-09-05 11:13:22] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:13:22] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:13:22] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:13:22] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149671803.00000000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:18:06] live.INFO: filterProduct method called {"business_id":8,"search_term":"nail","location_id":"9","not_for_selling":"0","price_group_id":"0","product_types":[],"search_fields":["name","sku","lot"],"check_qty":false,"search_type":"like"} 
[2026-09-05 11:18:06] live.DEBUG: Initial query built with joins {"has_location":true} 
[2026-09-05 11:18:06] live.DEBUG: Filtering by not_for_selling {"not_for_selling":"0"} 
[2026-09-05 11:18:06] live.DEBUG: Joining purchase_lines for lot number search  
[2026-09-05 11:18:06] live.DEBUG: Applying search filters {"search_term":"nail","search_type":"like","search_fields":["name","sku","lot"]} 
[2026-09-05 11:18:06] live.DEBUG: LIKE search conditions applied {"fields":["name","sku","lot"]} 
[2026-09-05 11:18:06] live.DEBUG: Applying location filter {"location_id":"9"} 
[2026-09-05 11:18:06] live.DEBUG: Added lot number fields to select  
[2026-09-05 11:18:06] live.INFO: filterProduct completed successfully {"result_count":1,"business_id":8,"search_term":"nail"} 
[2026-09-05 11:18:07] live.INFO: Product Row Debug - RELOADED {"product_id":339,"product_name":"Nails 10 inche","discount_allowed":false,"has_global_discount":false,"global_discount_type":"fixed","global_discount_amount":0,"discounts_count":0,"discounts":[],"base_price":10.0,"discounts_json":"[]","multiplier":1,"unit_prices":{"251":{"unit_id":251,"unit_name":"Pc","unit_price":10.0,"multiplier":1,"has_price":true},"253":{"unit_id":253,"unit_name":"Pkt","unit_price":265.0,"multiplier":"56.0000","has_price":true}},"has_price_group":false,"price_group_id":null} 
[2026-09-05 11:18:09] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:18:39] live.INFO: Credit Limit Check Started {"contact_id":"94","status":"final","final_total":"10.00","is_credit_sale":"0","exclude_transaction_id":null} 
[2026-09-05 11:18:39] live.DEBUG: Payment Calculation {"final_total":10.0,"curr_total_payment":10.0,"is_credit_sale":false,"payment_count":1} 
[2026-09-05 11:18:39] live.INFO: Credit Limit Check Skipped - Fully Paid {"final_total":10.0,"curr_total_payment":10.0} 
[2026-09-05 11:18:39] live.INFO: mpesa_transaction_id value: NULL  
[2026-09-05 11:18:39] live.INFO: is_mpesa_sale value: true  
[2026-09-05 11:18:39] live.INFO: M-Pesa sale evaluation {"is_mpesa_sale_raw":true,"is_valid_mpesa_sale":false,"payment_method_input":"cash","mpesa_transaction_id":null,"transaction_id":1821} 
[2026-09-05 11:18:39] live.INFO: Journal Entry Case: FULL CASH PAYMENT {"transaction_id":1821,"final_total":10.0,"amount_paid":10.0,"balance_due":0} 
[2026-09-05 11:18:39] live.INFO: Journal Entries Inserted Successfully {"transaction_id":1821,"entries":[{"transaction_id":1821,"created_by_id":21,"transaction_number":"TRX-6a9bd05f42dca5.80936710","payment_detail_id":1303,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:18:39","updated_at":"2026-09-05 11:18:39","chart_of_account_id":23,"debit":null,"credit":10.0},{"transaction_id":1821,"created_by_id":21,"transaction_number":"TRX-6a9bd05f42dca5.80936710","payment_detail_id":1303,"location_id":"9","currency_id":133,"transaction_type":"sell","date":"2026-09-05","month":9,"year":2026,"active":1,"reversed":0,"reversible":1,"manual_entry":1,"created_at":"2026-09-05 11:18:39","updated_at":"2026-09-05 11:18:39","chart_of_account_id":27,"debit":10.0,"credit":null}]} 
[2026-09-05 11:18:39] live.INFO: Inserted purchase sell mapping {"count":1,"data":[{"sell_line_id":1164,"purchase_line_id":1573,"quantity":1.0,"created_at":"2026-09-05 11:18:39","updated_at":"2026-09-05 11:18:39"}]} 
[2026-09-05 11:18:39] live.INFO: Inserted COGS → Inventory journal entries {"count":2} 
[2026-09-05 11:18:39] live.INFO: Inserted Retained Earnings (profit) entries {"count":1,"total_profit":5.0} 
[2026-09-05 11:18:39] live.INFO: ETIMS: Customer details retrieved {"transaction_id":1821,"contact_id":94,"customer_name":"Walk-In Customer","has_tin":false,"has_digitax_id":false} 
[2026-09-05 11:18:39] live.ERROR: ETIMS: Missing item_id for product {"product_id":339} 
[2026-09-05 11:18:39] live.ERROR: ETIMS: No valid items to submit after filtering  
[2026-09-05 11:18:39] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1821  
[2026-09-05 11:19:59] live.INFO: === BALANCE SHEET REQUEST ===  
[2026-09-05 11:19:59] live.INFO: Business ID: 8  
[2026-09-05 11:19:59] live.INFO: Fiscal Year: 2026  
[2026-09-05 11:19:59] live.INFO: As Of Date: 2026-12-31  
[2026-09-05 11:19:59] live.INFO: Location ID: All  
[2026-09-05 11:19:59] live.INFO: --- Starting getBalanceSheetData ---  
[2026-09-05 11:19:59] live.INFO: Permitted locations: all  
[2026-09-05 11:19:59] live.INFO: Fiscal Year: 2026  
[2026-09-05 11:19:59] live.INFO: Fiscal Year Start: 2026-01-01  
[2026-09-05 11:19:59] live.INFO: As Of Date: 2026-12-31  
[2026-09-05 11:19:59] live.INFO: --- Getting Non-Current Assets ---  
[2026-09-05 11:19:59] live.INFO: Querying assets table for business_id: 8 with purchase_date <= 2026-12-31  
[2026-09-05 11:19:59] live.INFO: Found 1 assets purchased on or before 2026-12-31  
[2026-09-05 11:19:59] live.INFO: Asset: Machine A - Purchase Date: 2026-07-01, Purchase Cost: 800000  
[2026-09-05 11:19:59] live.INFO: Added to non-current assets: Machine A - Value: 800000  
[2026-09-05 11:19:59] live.INFO: Non-Current Assets Count: 1  
[2026-09-05 11:19:59] live.INFO: Non-Current Assets Total: 800000  
[2026-09-05 11:19:59] live.INFO: --- Getting Current Assets ---  
[2026-09-05 11:19:59] live.INFO: --- Getting Method Balances ---  
[2026-09-05 11:19:59] live.INFO: Getting method balances up to date: 2026-12-31 (converted to: 2026-12-31)  
[2026-09-05 11:19:59] live.INFO: Found 358 payment records  
[2026-09-05 11:19:59] live.INFO: Method Balances:  {"Cash":-36008721.0,"Paybill Saf":194090.0,"Mpesa Till":24136.0,"Paybill Equity":256237.0,"Bank transfer":-19490053.0,"Card":5.0,"Jambo Pay":20334.0,"Pochi La Biashara":8052.0,"card":20061.0,"Mpesa Agent":53.0} 
[2026-09-05 11:19:59] live.INFO: Added Liability - Cash Overdraft: 36008721  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Paybill Saf, Balance: 194090  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Mpesa Till, Balance: 24136  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Paybill Equity, Balance: 256237  
[2026-09-05 11:19:59] live.INFO: Added Liability - Bank transfer Overdraft: 19490053  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Card, Balance: 5  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Jambo Pay, Balance: 20334  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Pochi La Biashara, Balance: 8052  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: card, Balance: 20061  
[2026-09-05 11:19:59] live.INFO: Added Current Asset - Method: Mpesa Agent, Balance: 53  
[2026-09-05 11:19:59] live.INFO: --- Getting Receivables ---  
[2026-09-05 11:19:59] live.INFO: Calculating receivables up to date: 2026-12-31  
[2026-09-05 11:19:59] live.INFO: Total Receivables: 5138387.0000  
[2026-09-05 11:19:59] live.INFO: Accounts Receivable: 5138387  
[2026-09-05 11:19:59] live.INFO: --- Getting Inventory Closing Stock Value as of 2026-12-31 ---  
[2026-09-05 11:19:59] live.INFO: Calculating closing stock value as of: 2026-12-31  
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":[],"permitted_locations":"all"} 
[2026-09-05 11:19:59] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:19:59] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539703.97360000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:19:59] live.INFO: Closing Stock Value (by purchase price): 148539703.97360000  
[2026-09-05 11:19:59] live.INFO: Inventory Closing Stock Value: 148539703.9736  
[2026-09-05 11:19:59] live.INFO: --- Getting Opening Stock Equity as of 2026-01-01 ---  
[2026-09-05 11:19:59] live.INFO: Calculating opening stock value as of: 2026-01-01  
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":[],"permitted_locations":"all"} 
[2026-09-05 11:19:59] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2025-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:19:59] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2025-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":0,"is_opening":false,"date":"2025-12-31"} 
[2026-09-05 11:19:59] live.INFO: Opening Stock Value (as of 2025-12-31): 0  
[2026-09-05 11:19:59] live.INFO: Opening Stock Equity: 0  
[2026-09-05 11:19:59] live.INFO: --- Getting Profit/Loss Details from TransactionUtil for Period ---  
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2025-12-31","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:19:59] live.INFO: Opening stock calculation - including all transactions {"date":"2025-12-31"} 
[2026-09-05 11:19:59] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2025-12-31')"} 
[2026-09-05 11:19:59] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2025-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2025-12-31'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"58905818.27480000","is_opening":true,"date":"2025-12-31"} 
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-12-31","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":"all"} 
[2026-09-05 11:19:59] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-12-31' (includes all types except purchase_order)"} 
[2026-09-05 11:19:59] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-12-31') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-12-31'","bindings":["purchase_order",8]} 
[2026-09-05 11:19:59] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539703.97360000","is_opening":false,"date":"2026-12-31"} 
[2026-09-05 11:19:59] live.INFO: Net Profit for Period 2026-01-01 to 2026-12-31: 3453818.1752  
[2026-09-05 11:19:59] live.INFO: Added to Equity - Retained Earnings: 3453818.1752  
[2026-09-05 11:19:59] live.INFO: --- Getting Payables ---  
[2026-09-05 11:19:59] live.INFO: Calculating payables up to date: 2026-12-31  
[2026-09-05 11:19:59] live.INFO: Total Payables: 2617835.7700  
[2026-09-05 11:19:59] live.INFO: Accounts Payable: 2617835.77  
[2026-09-05 11:19:59] live.INFO: === FINAL TOTALS ===  
[2026-09-05 11:19:59] live.INFO: Total Non-Current Assets: 800000  
[2026-09-05 11:19:59] live.INFO: Total Current Assets: 154201058.9736  
[2026-09-05 11:19:59] live.INFO: Total Assets: 155001058.9736  
[2026-09-05 11:19:59] live.INFO: Total Equity: 3453818.1752  
[2026-09-05 11:19:59] live.INFO: Total Liabilities: 58116609.77  
[2026-09-05 11:19:59] live.INFO: Total Equity + Liabilities: 61570427.9452  
[2026-09-05 11:19:59] live.INFO: Difference: 93430631.0284  
[2026-09-05 11:19:59] live.INFO: Is Balanced: No  
[2026-09-05 11:19:59] live.INFO: === BALANCE SHEET RESPONSE ===  
[2026-09-05 11:19:59] live.INFO: Total Assets: 155001058.9736  
[2026-09-05 11:19:59] live.INFO: Total Equity: 3453818.1752  
[2026-09-05 11:19:59] live.INFO: Total Liabilities: 58116609.77  
[2026-09-05 11:19:59] live.INFO: Is Balanced: No  
[2026-09-05 11:20:22] live.INFO: Calculating receivables listing from: 2026-09-05 to: 2026-09-05  
[2026-09-05 11:20:22] live.INFO: Calculating payables listing from: 2026-09-05 to: 2026-09-05  
[2026-09-05 11:20:27] live.INFO: Calculating receivables listing from: 2026-01-01 to: 2026-09-05  
[2026-09-05 11:20:27] live.INFO: Calculating payables listing from: 2026-01-01 to: 2026-09-05  
[2026-09-05 11:25:20] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"category_id":null,"sub_category_id":null,"brand_id":null,"unit_id":null},"permitted_locations":"all"} 
[2026-09-05 11:25:20] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:25:20] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:25:20] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539703.97360000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:25:20] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":true,"filters":{"category_id":null,"sub_category_id":null,"brand_id":null,"unit_id":null},"permitted_locations":"all"} 
[2026-09-05 11:25:20] live.DEBUG: Using sale price instead of purchase price {"price_query_part":"v.sell_price_inc_tax"} 
[2026-09-05 11:25:20] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:25:20] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * v.sell_price_inc_tax
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:25:20] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"149671793.00000000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:26:10] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 11:26:10] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 11:26:10] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 11:26:10] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:26:10] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147661370.89360000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 11:26:10] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 11:26:10] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:26:10] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:26:10] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539703.97360000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:26:40] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:30:38] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:30:41] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-04","location_id":null,"is_opening":true,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 11:30:41] live.INFO: Opening stock calculation - including all transactions {"date":"2026-09-04"} 
[2026-09-05 11:30:41] live.INFO: Applied opening stock condition {"condition":"purchase.type = 'opening_stock' OR (purchase.type != 'opening_stock' AND date(transaction_date) <= '2026-09-04')"} 
[2026-09-05 11:30:41] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-04') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and (`purchase`.`type` = ? or (`purchase`.`type` != ? and date(transaction_date) <= '2026-09-04'))","bindings":["purchase_order",8,"opening_stock","opening_stock"]} 
[2026-09-05 11:30:41] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"147661370.89360000","is_opening":true,"date":"2026-09-04"} 
[2026-09-05 11:30:41] live.INFO: === getOpeningClosingStock START === {"business_id":8,"date":"2026-09-05","location_id":null,"is_opening":false,"by_sale_price":false,"filters":{"user_id":null},"permitted_locations":null} 
[2026-09-05 11:30:41] live.INFO: Applied closing stock condition {"condition":"date(transaction_date) <= '2026-09-05' (includes all types except purchase_order)"} 
[2026-09-05 11:30:41] live.DEBUG: Final SQL Query {"sql":"select SUM((purchase_lines.quantity - purchase_lines.quantity_returned - purchase_lines.quantity_adjusted -
                        (SELECT COALESCE(SUM(tspl.quantity - tspl.qty_returned), 0) FROM 
                        transaction_sell_lines_purchase_lines AS tspl
                        JOIN transaction_sell_lines as tsl ON 
                        tspl.sell_line_id=tsl.id 
                        JOIN transactions as sale ON 
                        tsl.transaction_id=sale.id 
                        WHERE tspl.purchase_line_id = purchase_lines.id AND 
                        date(sale.transaction_date) <= '2026-09-05') ) * (purchase_lines.purchase_price + 
                        COALESCE(purchase_lines.item_tax, 0))
                    ) as stock from `purchase_lines` inner join `transactions` as `purchase` on `purchase_lines`.`transaction_id` = `purchase`.`id` left join `variations` as `v` on `v`.`id` = `purchase_lines`.`variation_id` left join `products` as `p` on `p`.`id` = `purchase_lines`.`product_id` where `purchase`.`type` != ? and `purchase`.`business_id` = ? and date(transaction_date) <= '2026-09-05'","bindings":["purchase_order",8]} 
[2026-09-05 11:30:41] live.INFO: === getOpeningClosingStock RESULT === {"calculated_stock":"148539703.97360000","is_opening":false,"date":"2026-09-05"} 
[2026-09-05 11:30:57] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:32:16] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1821  
[2026-09-05 11:36:26] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
[2026-09-05 11:36:50] live.WARNING: ETIMS WAIT: Timed out after 2 attempts for transaction ID: 1821  
[2026-09-05 12:21:19] live.ERROR: Failed to send error alert email: Failed to authenticate on SMTP server with username "support@risetsystems.com" using the following authenticators: "LOGIN", "PLAIN". Authenticator "LOGIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".". Authenticator "PLAIN" returned "Expected response code "235" but got code "535", with message "535 Incorrect authentication data".".  
