summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-08-20 10:04:10 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-08-20 10:04:10 +0700
commit1d44c04f3ec25d3adc19eb8e34589c6461ef8a66 (patch)
tree67628db6ea9a65baef5372d8a8760a20ac0df99c
parentc225119cb9bdcee03ca9706ec58dfceb717b5027 (diff)
fix bug percentpie retur
-rwxr-xr-xindoteknik_custom/models/sale_order.py57
-rw-r--r--indoteknik_custom/models/sale_order_line.py34
-rwxr-xr-xindoteknik_custom/views/sale_order.xml4
3 files changed, 72 insertions, 23 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 80790ebe..53be999f 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -388,8 +388,37 @@ class SaleOrder(models.Model):
string="Unreserved %", digits=(16, 2),
compute="_compute_reserved_delivered_pie", store=False
)
+ payment_state_custom = fields.Selection([
+ ('unpaid', 'Unpaid'),
+ ('partial', 'Partially Paid'),
+ ('paid', 'Paid'),
+ ('no_invoice', 'No Invoice'),
+ ], string="Payment Status", 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.reserved_percent', 'order_line.delivered_percent', 'order_line.unreserved_percent')
+ @api.depends('order_line.move_ids.state',
+ 'order_line.move_ids.reserved_availability',
+ 'order_line.move_ids.quantity_done')
def _compute_reserved_delivered_pie(self):
for order in self:
total_qty = sum(order.order_line.mapped('product_uom_qty'))
@@ -401,16 +430,23 @@ class SaleOrder(models.Model):
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'))
+ for move in line.move_ids:
+ if move.state != 'done':
+ # reserve qty (draft/assigned)
+ if move.picking_type_id.code == 'internal':
+ reserved_qty += move.reserved_availability or 0.0
+ continue
- 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'))
+ # sudah done → cek alur lokasi
+ if move.location_dest_id.usage == 'customer':
+ # barang keluar → delivered
+ delivered_qty += move.quantity_done
+ elif move.location_id.usage == 'customer':
+ # barang balik (return) → kurangi delivered
+ delivered_qty -= move.quantity_done
+
+ # clamp biar ga minus
+ delivered_qty = max(delivered_qty, 0)
order.reserved_percent = (reserved_qty / total_qty) * 100
order.delivered_percent = (delivered_qty / total_qty) * 100
@@ -418,6 +454,7 @@ class SaleOrder(models.Model):
else:
order.reserved_percent = order.delivered_percent = order.unreserved_percent = 0
+
def _has_ccm(self):
if self.id:
self.ccm_id = self.env['tukar.guling'].search([('origin', 'ilike', self.name)], limit=1)
diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py
index 2a00bac0..2406995d 100644
--- a/indoteknik_custom/models/sale_order_line.py
+++ b/indoteknik_custom/models/sale_order_line.py
@@ -58,31 +58,39 @@ class SaleOrderLine(models.Model):
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')
+ @api.depends('move_ids.state', 'move_ids.reserved_availability', 'move_ids.quantity_done')
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'))
-
+ for move in line.move_ids:
+ if move.state != 'done':
+ # Reserve qty (hanya dari picking internal yang belum selesai)
+ if move.picking_type_id.code == 'internal':
+ reserved_qty += move.reserved_availability or 0.0
+ continue
+
+ # Kalau sudah done → cek lokasi
+ if move.location_dest_id.usage == 'customer':
+ # Barang keluar → tambah delivered
+ delivered_qty += move.quantity_done
+ elif move.location_id.usage == 'customer':
+ # Barang balik dari customer (retur) → kurangi delivered
+ delivered_qty -= move.quantity_done
+
+ # Jangan sampai delivered minus
+ delivered_qty = max(delivered_qty, 0)
+
+ # Hitung persentase
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):
outgoing_moves = self.env['stock.move']
incoming_moves = self.env['stock.move']
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 5fad5700..be31456b 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -483,6 +483,10 @@
<field name="date_kirim_ril"/>
<field name="date_driver_departure"/>
<field name="date_driver_arrival"/>
+ <field name="payment_state_custom" widget="badge"
+ decoration-danger="payment_state_custom == 'unpaid'"
+ decoration-success="payment_state_custom == 'paid'"
+ decoration-warning="payment_state_custom == 'partial'"/>
<field name="unreserved_percent" widget="percentpie" string="Unreserved"/>
<field name="reserved_percent" widget="percentpie" string="Reserved"/>
<field name="delivered_percent" widget="percentpie" string="Delivered"/>