summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/sale_order.py
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2025-08-30 09:25:35 +0700
committerit-fixcomart <it@fixcomart.co.id>2025-08-30 09:25:35 +0700
commit5ef97855847141eaa705be36a2aae17cdf928258 (patch)
tree449d86549d69024e92032b2246f8481bf081302a /indoteknik_custom/models/sale_order.py
parent0298605049e29ef436a5e6984b743f89fed712b3 (diff)
parent63426e9de8700daff0c0f7cf0389d2be55e982fb (diff)
<hafid> fix conflict merge
Diffstat (limited to 'indoteknik_custom/models/sale_order.py')
-rwxr-xr-xindoteknik_custom/models/sale_order.py77
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: