diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-08-19 14:02:45 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-08-19 14:02:45 +0700 |
| commit | e2d186dd98b2c0d1bc9bab8ea9b7d80c59873046 (patch) | |
| tree | 2150fbe6c6cf198da9c565777ea9d838ef8d6738 | |
| parent | 6fc6511bdfd530d5e1f89fd5e4cb672a632a51f0 (diff) | |
add percent pie on sale order
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 41 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 27 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 6 |
3 files changed, 74 insertions, 0 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 0acfa0b0..80790ebe 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -376,6 +376,47 @@ class SaleOrder(models.Model): compute='_compute_advance_payment_moves', store=False ) + reserved_percent = fields.Float( + string="Reserved %", digits=(16, 2), + compute="_compute_reserved_delivered_pie", store=False + ) + delivered_percent = fields.Float( + string="Delivered %", digits=(16, 2), + compute="_compute_reserved_delivered_pie", store=False + ) + unreserved_percent = fields.Float( + string="Unreserved %", digits=(16, 2), + compute="_compute_reserved_delivered_pie", store=False + ) + + @api.depends('order_line.reserved_percent', 'order_line.delivered_percent', 'order_line.unreserved_percent') + def _compute_reserved_delivered_pie(self): + for order in self: + total_qty = sum(order.order_line.mapped('product_uom_qty')) + reserved_qty = delivered_qty = 0.0 + + if total_qty > 0: + for line in order.order_line: + order_qty = line.product_uom_qty or 0.0 + if not order_qty: + continue + + # ambil qty asli dari move, bukan percent agar akurat + pick_moves = line.move_ids.filtered( + lambda m: m.picking_type_id.code == 'internal' and m.state not in ('done', 'cancel') + ) + reserved_qty += sum(pick_moves.mapped('reserved_availability')) + + out_moves = line.move_ids.filtered( + lambda m: m.picking_type_id.code == 'outgoing' and m.state == 'done' + ) + delivered_qty += sum(out_moves.mapped('quantity_done')) + + order.reserved_percent = (reserved_qty / total_qty) * 100 + order.delivered_percent = (delivered_qty / total_qty) * 100 + order.unreserved_percent = 100 - order.reserved_percent - order.delivered_percent + else: + order.reserved_percent = order.delivered_percent = order.unreserved_percent = 0 def _has_ccm(self): if self.id: diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 64b9f9bc..2a00bac0 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -54,6 +54,33 @@ class SaleOrderLine(models.Model): desc_updatable = fields.Boolean(string='desc boolean', default=True, compute='_get_desc_updatable') is_has_disc = fields.Boolean('Flash Sale', default=False) + reserved_percent = fields.Float(string="Reserved %", digits=(16, 2), compute="_compute_reserved_delivered_pie", store=False) + delivered_percent = fields.Float(string="Delivered %", digits=(16, 2), compute="_compute_reserved_delivered_pie", store=False) + unreserved_percent = fields.Float(string="Unreserved %", digits=(16, 2), compute="_compute_reserved_delivered_pie", store=False) + + @api.depends('move_ids') + def _compute_reserved_delivered_pie(self): + for line in self: + order_qty = line.product_uom_qty or 0.0 + reserved_qty = delivered_qty = 0.0 + + if order_qty > 0: + # Reserved: hanya dari BU/PICK yang masih aktif + pick_moves = line.move_ids.filtered( + lambda m: m.picking_type_id.code == 'internal' and m.state not in ('done', 'cancel') + ) + reserved_qty = sum(pick_moves.mapped('reserved_availability')) + + # Delivered: hanya dari BU/OUT yang sudah done + out_moves = line.move_ids.filtered( + lambda m: m.picking_type_id.code == 'outgoing' and m.state == 'done' + ) + delivered_qty = sum(out_moves.mapped('quantity_done')) + + line.reserved_percent = (reserved_qty / order_qty) * 100 if order_qty else 0 + line.delivered_percent = (delivered_qty / order_qty) * 100 if order_qty else 0 + line.unreserved_percent = 100 - line.reserved_percent - line.delivered_percent + def _get_outgoing_incoming_moves(self): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 868bce7b..518bc9d6 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -290,6 +290,9 @@ <field name="note" optional="hide"/> <field name="note_procurement" optional="hide"/> <field name="vendor_subtotal" optional="hide"/> + <field name="unreserved_percent" widget="percentpie" string="Unreserved"/> + <field name="reserved_percent" widget="percentpie" string="Reserved"/> + <field name="delivered_percent" widget="percentpie" string="Delivered"/> <field name="weight" optional="hide"/> <field name="is_has_disc" string="Flash Sale Item?" readonly="1" optional="hide"/> <field name="amount_voucher_disc" string="Voucher" readonly="1" optional="hide"/> @@ -461,6 +464,9 @@ <field name="pareto_status" optional="hide"/> <field name="shipping_method_picking" optional="hide"/> <field name="hold_outgoing" optional="hide"/> + <field name="reserved_percent" widget="percentpie" string="Reserved"/> + <field name="delivered_percent" widget="percentpie" string="Delivered"/> + <field name="unreserved_percent" widget="percentpie" string="Unreserved"/> </field> </field> </record> |
