diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-08-30 09:25:35 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-08-30 09:25:35 +0700 |
| commit | 5ef97855847141eaa705be36a2aae17cdf928258 (patch) | |
| tree | 449d86549d69024e92032b2246f8481bf081302a /indoteknik_custom/models/sale_order.py | |
| parent | 0298605049e29ef436a5e6984b743f89fed712b3 (diff) | |
| parent | 63426e9de8700daff0c0f7cf0389d2be55e982fb (diff) | |
<hafid> fix conflict merge
Diffstat (limited to 'indoteknik_custom/models/sale_order.py')
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 998363ef..903f834b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -375,6 +375,83 @@ 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 + ) + payment_state_custom = fields.Selection([ + ('unpaid', 'Unpaid'), + ('partial', 'Partially Paid'), + ('paid', 'Full Paid'), + ('no_invoice', 'No Invoice'), + ], string="Payment Status Invoice", compute="_compute_payment_state_custom", store=False) + + @api.depends('invoice_ids.payment_state', 'invoice_ids.amount_total', 'invoice_ids.amount_residual') + def _compute_payment_state_custom(self): + for order in self: + invoices = order.invoice_ids.filtered(lambda inv: inv.state != 'cancel') + total = sum(invoices.mapped('amount_total')) + residual = sum(invoices.mapped('amount_residual')) + + if not invoices or total == 0: + order.payment_state_custom = 'no_invoice' + continue + + paid = total - residual + percent_paid = (paid / total) * 100 if total > 0 else 0.0 + + if percent_paid == 100: + order.payment_state_custom = 'paid' + elif percent_paid == 0: + order.payment_state_custom = 'unpaid' + else: + order.payment_state_custom = 'partial' + + @api.depends( + 'order_line.move_ids.state', + 'order_line.move_ids.reserved_availability', + 'order_line.move_ids.quantity_done', + 'order_line.move_ids.picking_type_id' + ) + def _compute_reserved_delivered_pie(self): + for order in self: + order_qty = sum(order.order_line.mapped('product_uom_qty')) or 0.0 + reserved_qty = delivered_qty = 0.0 + + if order_qty > 0: + # Kumpulin semua moves dari order + all_moves = order.order_line.mapped('move_ids') + + for move in all_moves: + # --- CASE 1: Move belum selesai --- + if move.state not in ('done', 'cancel'): + # Reserved qty hanya dari move yang belum selesai + reserved_qty += move.reserved_availability or 0.0 + continue + + # --- CASE 2: Move sudah done --- + if move.location_dest_id.usage == 'customer': + # Barang dikirim ke customer + delivered_qty += move.quantity_done or 0.0 + elif move.location_id.usage == 'customer': + # Barang balik dari customer (retur) + delivered_qty -= move.quantity_done or 0.0 + + # Clamp supaya delivered gak minus + delivered_qty = max(delivered_qty, 0) + + # Hitung persen + order.reserved_percent = min((reserved_qty / order_qty) * 100, 100) if order_qty else 0 + order.delivered_percent = min((delivered_qty / order_qty) * 100, 100) if order_qty else 0 + order.unreserved_percent = max(100 - order.reserved_percent - order.delivered_percent, 0) def _has_ccm(self): if self.id: |
