CREATE OR REPLACE VIEW public.vw_utility_trade_pnl_quantities AS WITH lot_current_qty AS ( SELECT l.id AS lot_id, round(((COALESCE(lh.quantity, (0)::numeric) * (COALESCE(lot_uom.factor, (1)::double precision))::numeric) / NULLIF((COALESCE(line_uom.factor, (1)::double precision))::numeric, (0)::numeric)), 5) AS pnl_quantity, lot_uom.name AS quantity_uom FROM (((((lot_lot l LEFT JOIN lot_qt_hist lh ON (((lh.lot = l.id) AND (lh.quantity_type = l.lot_state)))) LEFT JOIN product_uom lot_uom ON ((lot_uom.id = l.lot_unit_line))) LEFT JOIN purchase_line pl ON ((pl.id = l.line))) LEFT JOIN sale_line sl ON ((sl.id = l.sale_line))) LEFT JOIN product_uom line_uom ON ((line_uom.id = COALESCE(pl.unit, sl.unit)))) ), purchase_pnl_lots AS ( SELECT 'purchase'::text AS pnl_side, p.id AS purchase_id, p.number AS purchase_number, p.reference AS purchase_reference, pl.id AS purchase_line_id, pl.finished AS purchase_line_finished, s.id AS sale_id, s.number AS sale_number, s.reference AS sale_reference, sl.id AS sale_line_id, sl.finished AS sale_line_finished, l.id AS valued_lot_id, l.lot_type AS valued_lot_type, NULL::integer AS lot_qt_id, lcq.pnl_quantity, lcq.quantity_uom AS quantity_unit, pl.product AS product_id, COALESCE(shi.from_location, sint.from_location, sho.from_location, p.from_location) AS from_location_id, COALESCE(shi.to_location, sint.to_location, sho.to_location, p.to_location) AS to_location_id, shi.id AS shipment_id, shi.bl_date, pl.from_del AS delivery_date_from, pl.to_del AS delivery_date_to FROM ((((((((purchase_line pl JOIN purchase_purchase p ON ((p.id = pl.purchase))) JOIN lot_lot l ON ((l.line = pl.id))) JOIN lot_current_qty lcq ON ((lcq.lot_id = l.id))) LEFT JOIN sale_line sl ON ((sl.id = l.sale_line))) LEFT JOIN sale_sale s ON ((s.id = sl.sale))) LEFT JOIN stock_shipment_in shi ON ((shi.id = l.lot_shipment_in))) LEFT JOIN stock_shipment_internal sint ON ((sint.id = l.lot_shipment_internal))) LEFT JOIN stock_shipment_out sho ON ((sho.id = l.lot_shipment_out))) WHERE (((pl.type)::text = 'line'::text) AND ((l.lot_type)::text = ANY (ARRAY[('virtual'::character varying)::text, ('physic'::character varying)::text]))) ), sale_pnl_direct_lots AS ( SELECT 'sale'::text AS pnl_side, p.id AS purchase_id, p.number AS purchase_number, p.reference AS purchase_reference, pl.id AS purchase_line_id, pl.finished AS purchase_line_finished, s.id AS sale_id, s.number AS sale_number, s.reference AS sale_reference, sl.id AS sale_line_id, sl.finished AS sale_line_finished, l.id AS valued_lot_id, l.lot_type AS valued_lot_type, NULL::integer AS lot_qt_id, lcq.pnl_quantity, lcq.quantity_uom AS quantity_unit, sl.product AS product_id, COALESCE(shi.from_location, sint.from_location, sho.from_location, s.from_location) AS from_location_id, COALESCE(shi.to_location, sint.to_location, sho.to_location, s.to_location) AS to_location_id, shi.id AS shipment_id, shi.bl_date, sl.from_del AS delivery_date_from, sl.to_del AS delivery_date_to FROM ((((((((purchase_line pl JOIN purchase_purchase p ON ((p.id = pl.purchase))) JOIN lot_lot l ON (((l.line = pl.id) AND (l.sale_line IS NOT NULL)))) JOIN sale_line sl ON ((sl.id = l.sale_line))) JOIN sale_sale s ON ((s.id = sl.sale))) JOIN lot_current_qty lcq ON ((lcq.lot_id = l.id))) LEFT JOIN stock_shipment_in shi ON ((shi.id = l.lot_shipment_in))) LEFT JOIN stock_shipment_internal sint ON ((sint.id = l.lot_shipment_internal))) LEFT JOIN stock_shipment_out sho ON ((sho.id = l.lot_shipment_out))) WHERE (((pl.type)::text = 'line'::text) AND ((l.lot_type)::text = 'physic'::text) AND (NOT (EXISTS ( SELECT 1 FROM purchase_pnl_lots ppl WHERE ((ppl.valued_lot_id = l.id) AND (ppl.sale_line_id = sl.id)))))) ), sale_pnl_matched_virtual_lots AS ( SELECT 'sale'::text AS pnl_side, p.id AS purchase_id, p.number AS purchase_number, p.reference AS purchase_reference, pl.id AS purchase_line_id, pl.finished AS purchase_line_finished, s.id AS sale_id, s.number AS sale_number, s.reference AS sale_reference, sl.id AS sale_line_id, sl.finished AS sale_line_finished, sale_lot.id AS valued_lot_id, sale_lot.lot_type AS valued_lot_type, lqt.id AS lot_qt_id, lqt.lot_quantity AS pnl_quantity, lcq.quantity_uom AS quantity_unit, sl.product AS product_id, COALESCE(shi.from_location, sint.from_location, sho.from_location, s.from_location) AS from_location_id, COALESCE(shi.to_location, sint.to_location, sho.to_location, s.to_location) AS to_location_id, shi.id AS shipment_id, shi.bl_date, sl.from_del AS delivery_date_from, sl.to_del AS delivery_date_to FROM ((((((((((purchase_line pl JOIN purchase_purchase p ON ((p.id = pl.purchase))) JOIN lot_lot purchase_lot ON (((purchase_lot.line = pl.id) AND ((purchase_lot.lot_type)::text = 'virtual'::text) AND (purchase_lot.sale_line IS NULL)))) JOIN lot_qt lqt ON (((lqt.lot_p = purchase_lot.id) AND (lqt.lot_s IS NOT NULL) AND (lqt.lot_quantity > (0)::numeric)))) JOIN lot_lot sale_lot ON (((sale_lot.id = lqt.lot_s) AND ((sale_lot.lot_type)::text = 'virtual'::text)))) JOIN sale_line sl ON ((sl.id = sale_lot.sale_line))) JOIN sale_sale s ON ((s.id = sl.sale))) JOIN lot_current_qty lcq ON ((lcq.lot_id = sale_lot.id))) LEFT JOIN stock_shipment_in shi ON ((shi.id = lqt.lot_shipment_in))) LEFT JOIN stock_shipment_internal sint ON ((sint.id = lqt.lot_shipment_internal))) LEFT JOIN stock_shipment_out sho ON ((sho.id = lqt.lot_shipment_out))) WHERE ((pl.type)::text = 'line'::text) ), sale_pnl_unmatched_lots AS ( SELECT 'sale'::text AS pnl_side, NULL::integer AS purchase_id, NULL::character varying AS purchase_number, NULL::character varying AS purchase_reference, NULL::integer AS purchase_line_id, NULL::boolean AS purchase_line_finished, s.id AS sale_id, s.number AS sale_number, s.reference AS sale_reference, sl.id AS sale_line_id, sl.finished AS sale_line_finished, l.id AS valued_lot_id, l.lot_type AS valued_lot_type, NULL::integer AS lot_qt_id, lcq.pnl_quantity, lcq.quantity_uom AS quantity_unit, sl.product AS product_id, COALESCE(shi.from_location, sint.from_location, sho.from_location, s.from_location) AS from_location_id, COALESCE(shi.to_location, sint.to_location, sho.to_location, s.to_location) AS to_location_id, shi.id AS shipment_id, shi.bl_date, sl.from_del AS delivery_date_from, sl.to_del AS delivery_date_to FROM ((((((sale_line sl JOIN sale_sale s ON ((s.id = sl.sale))) JOIN lot_lot l ON (((l.sale_line = sl.id) AND (l.line IS NULL) AND ((l.lot_type)::text = ANY (ARRAY[('virtual'::character varying)::text, ('physic'::character varying)::text]))))) JOIN lot_current_qty lcq ON ((lcq.lot_id = l.id))) LEFT JOIN stock_shipment_in shi ON ((shi.id = l.lot_shipment_in))) LEFT JOIN stock_shipment_internal sint ON ((sint.id = l.lot_shipment_internal))) LEFT JOIN stock_shipment_out sho ON ((sho.id = l.lot_shipment_out))) WHERE (((sl.type)::text = 'line'::text) AND (NOT (EXISTS ( SELECT 1 FROM lot_qt lqt WHERE ((lqt.lot_s = l.id) AND (lqt.lot_p IS NOT NULL) AND (lqt.lot_quantity > (0)::numeric)))))) ), pnl_lot_rows AS ( SELECT purchase_pnl_lots.pnl_side, purchase_pnl_lots.purchase_id, purchase_pnl_lots.purchase_number, purchase_pnl_lots.purchase_reference, purchase_pnl_lots.purchase_line_id, purchase_pnl_lots.purchase_line_finished, purchase_pnl_lots.sale_id, purchase_pnl_lots.sale_number, purchase_pnl_lots.sale_reference, purchase_pnl_lots.sale_line_id, purchase_pnl_lots.sale_line_finished, purchase_pnl_lots.valued_lot_id, purchase_pnl_lots.valued_lot_type, purchase_pnl_lots.lot_qt_id, purchase_pnl_lots.pnl_quantity, purchase_pnl_lots.quantity_unit, purchase_pnl_lots.product_id, purchase_pnl_lots.from_location_id, purchase_pnl_lots.to_location_id, purchase_pnl_lots.shipment_id, purchase_pnl_lots.bl_date, purchase_pnl_lots.delivery_date_from, purchase_pnl_lots.delivery_date_to FROM purchase_pnl_lots UNION ALL SELECT sale_pnl_direct_lots.pnl_side, sale_pnl_direct_lots.purchase_id, sale_pnl_direct_lots.purchase_number, sale_pnl_direct_lots.purchase_reference, sale_pnl_direct_lots.purchase_line_id, sale_pnl_direct_lots.purchase_line_finished, sale_pnl_direct_lots.sale_id, sale_pnl_direct_lots.sale_number, sale_pnl_direct_lots.sale_reference, sale_pnl_direct_lots.sale_line_id, sale_pnl_direct_lots.sale_line_finished, sale_pnl_direct_lots.valued_lot_id, sale_pnl_direct_lots.valued_lot_type, sale_pnl_direct_lots.lot_qt_id, sale_pnl_direct_lots.pnl_quantity, sale_pnl_direct_lots.quantity_unit, sale_pnl_direct_lots.product_id, sale_pnl_direct_lots.from_location_id, sale_pnl_direct_lots.to_location_id, sale_pnl_direct_lots.shipment_id, sale_pnl_direct_lots.bl_date, sale_pnl_direct_lots.delivery_date_from, sale_pnl_direct_lots.delivery_date_to FROM sale_pnl_direct_lots UNION ALL SELECT sale_pnl_matched_virtual_lots.pnl_side, sale_pnl_matched_virtual_lots.purchase_id, sale_pnl_matched_virtual_lots.purchase_number, sale_pnl_matched_virtual_lots.purchase_reference, sale_pnl_matched_virtual_lots.purchase_line_id, sale_pnl_matched_virtual_lots.purchase_line_finished, sale_pnl_matched_virtual_lots.sale_id, sale_pnl_matched_virtual_lots.sale_number, sale_pnl_matched_virtual_lots.sale_reference, sale_pnl_matched_virtual_lots.sale_line_id, sale_pnl_matched_virtual_lots.sale_line_finished, sale_pnl_matched_virtual_lots.valued_lot_id, sale_pnl_matched_virtual_lots.valued_lot_type, sale_pnl_matched_virtual_lots.lot_qt_id, sale_pnl_matched_virtual_lots.pnl_quantity, sale_pnl_matched_virtual_lots.quantity_unit, sale_pnl_matched_virtual_lots.product_id, sale_pnl_matched_virtual_lots.from_location_id, sale_pnl_matched_virtual_lots.to_location_id, sale_pnl_matched_virtual_lots.shipment_id, sale_pnl_matched_virtual_lots.bl_date, sale_pnl_matched_virtual_lots.delivery_date_from, sale_pnl_matched_virtual_lots.delivery_date_to FROM sale_pnl_matched_virtual_lots UNION ALL SELECT sale_pnl_unmatched_lots.pnl_side, sale_pnl_unmatched_lots.purchase_id, sale_pnl_unmatched_lots.purchase_number, sale_pnl_unmatched_lots.purchase_reference, sale_pnl_unmatched_lots.purchase_line_id, sale_pnl_unmatched_lots.purchase_line_finished, sale_pnl_unmatched_lots.sale_id, sale_pnl_unmatched_lots.sale_number, sale_pnl_unmatched_lots.sale_reference, sale_pnl_unmatched_lots.sale_line_id, sale_pnl_unmatched_lots.sale_line_finished, sale_pnl_unmatched_lots.valued_lot_id, sale_pnl_unmatched_lots.valued_lot_type, sale_pnl_unmatched_lots.lot_qt_id, sale_pnl_unmatched_lots.pnl_quantity, sale_pnl_unmatched_lots.quantity_unit, sale_pnl_unmatched_lots.product_id, sale_pnl_unmatched_lots.from_location_id, sale_pnl_unmatched_lots.to_location_id, sale_pnl_unmatched_lots.shipment_id, sale_pnl_unmatched_lots.bl_date, sale_pnl_unmatched_lots.delivery_date_from, sale_pnl_unmatched_lots.delivery_date_to FROM sale_pnl_unmatched_lots ), pnl_lot_rows_with_finished AS ( SELECT pnl_lot_rows.pnl_side, pnl_lot_rows.purchase_id, pnl_lot_rows.purchase_number, pnl_lot_rows.purchase_reference, pnl_lot_rows.purchase_line_id, pnl_lot_rows.purchase_line_finished, pnl_lot_rows.sale_id, pnl_lot_rows.sale_number, pnl_lot_rows.sale_reference, pnl_lot_rows.sale_line_id, pnl_lot_rows.sale_line_finished, pnl_lot_rows.valued_lot_id, pnl_lot_rows.valued_lot_type, pnl_lot_rows.lot_qt_id, pnl_lot_rows.pnl_quantity, pnl_lot_rows.quantity_unit, pnl_lot_rows.product_id, pnl_lot_rows.from_location_id, pnl_lot_rows.to_location_id, pnl_lot_rows.shipment_id, pnl_lot_rows.bl_date, pnl_lot_rows.delivery_date_from, pnl_lot_rows.delivery_date_to, CASE WHEN (pnl_lot_rows.pnl_side = 'purchase'::text) THEN pnl_lot_rows.purchase_line_finished WHEN (pnl_lot_rows.pnl_side = 'sale'::text) THEN pnl_lot_rows.sale_line_finished ELSE false END AS valued_line_finished, CASE WHEN (((pnl_lot_rows.valued_lot_type)::text = 'virtual'::text) AND (((pnl_lot_rows.pnl_side = 'purchase'::text) AND (pnl_lot_rows.purchase_line_finished IS TRUE)) OR ((pnl_lot_rows.pnl_side = 'sale'::text) AND (pnl_lot_rows.sale_line_finished IS TRUE)))) THEN true ELSE false END AS ignored_by_finished_rule FROM pnl_lot_rows ) SELECT pnl_side, purchase_id, purchase_number, purchase_reference, purchase_line_id, purchase_line_finished, sale_id, sale_number, sale_reference, sale_line_id, sale_line_finished, valued_lot_id, valued_lot_type, valued_line_finished, ignored_by_finished_rule, sum(pnl_quantity) AS pnl_quantity_raw, sum( CASE WHEN ignored_by_finished_rule THEN (0)::numeric ELSE pnl_quantity END) AS pnl_quantity_after_finished_rule, quantity_unit, product_id, from_location_id, to_location_id, shipment_id, bl_date, delivery_date_from, delivery_date_to FROM pnl_lot_rows_with_finished GROUP BY pnl_side, purchase_id, purchase_number, purchase_reference, purchase_line_id, purchase_line_finished, sale_id, sale_number, sale_reference, sale_line_id, sale_line_finished, valued_lot_type, valued_lot_id, valued_line_finished, ignored_by_finished_rule, quantity_unit, product_id, from_location_id, to_location_id, shipment_id, bl_date, delivery_date_from, delivery_date_to;;