From abe9e16dff1d7b65530b258a306a6376b71c655b Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 23 Jan 2026 13:39:30 +0700 Subject: cashback brand --- indoteknik_custom/models/sale_order_line.py | 17 +++++++++++++++++ indoteknik_custom/models/x_manufactures.py | 2 +- indoteknik_custom/views/sale_order.xml | 1 + indoteknik_custom/views/x_manufactures.xml | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 1df1a058..7b97bd85 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -17,6 +17,7 @@ class SaleOrderLine(models.Model): help="Total % Margin in Sales Order Header") item_percent_margin_before = fields.Float('%Margin Before', compute='_compute_item_percent_margin_before', help="Total % Margin excluding third party in Sales Order Header") + amount_cashback = fields.Float('Cashback Brand', compute='_compute_cashback_brand', help='Cashback from product who has cashback percent in manufacture') initial_discount = fields.Float('Initial Discount') vendor_id = fields.Many2one( 'res.partner', string='Vendor', readonly=True, @@ -212,6 +213,8 @@ class SaleOrderLine(models.Model): sales_price -= line.delivery_amt_line # if line.order_id.fee_third_party > 0: # sales_price -= line.fee_third_party_line + if line.amount_cashback > 0: + sales_price += line.amount_cashback purchase_price = line.purchase_price if line.purchase_tax_id.price_include: @@ -247,6 +250,20 @@ class SaleOrderLine(models.Model): margin_per_item = sales_price - purchase_price line.item_before_margin = margin_per_item + def _compute_cashback_brand(self): + for line in self: + line.amount_cashback = 0 + + if not line.product_id: + continue + + cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 + if cashback_percent <= 0: + continue + + price, taxes, vendor_id = self._get_purchase_price(line.product_id) + line.amount_cashback = price * cashback_percent + # @api.onchange('vendor_id') # def onchange_vendor_id(self): # # TODO : need to change this logic @stephan diff --git a/indoteknik_custom/models/x_manufactures.py b/indoteknik_custom/models/x_manufactures.py index 9e214d92..0c3bfa3b 100755 --- a/indoteknik_custom/models/x_manufactures.py +++ b/indoteknik_custom/models/x_manufactures.py @@ -50,7 +50,7 @@ class XManufactures(models.Model): # user_id = fields.Many2one('res.users', string='Responsible', domain="['|'('id', '=', 19), ('id', '=', 6)]", help="Siapa yang bertanggung jawab") user_id = fields.Many2one('res.users', string='Responsible', help="Siapa yang bertanggung jawab") override_vendor_id = fields.Many2one('res.partner', string='Override Vendor') - # cashback_percent = fields.Float(string='Cashback Percent') + cashback_percent = fields.Float(string='Cashback Percent', default=0) def _compute_vendor_ids(self): for manufacture in self: diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 23fbe155..c3df92ec 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -302,6 +302,7 @@ ] } "/> + - + -- cgit v1.2.3 From d74fa661fad2d83483d23e935836165359c0a1d2 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Tue, 27 Jan 2026 09:47:05 +0700 Subject: cashback brand done --- indoteknik_custom/models/sale_order_line.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 7b97bd85..c9e75fc7 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -213,12 +213,13 @@ class SaleOrderLine(models.Model): sales_price -= line.delivery_amt_line # if line.order_id.fee_third_party > 0: # sales_price -= line.fee_third_party_line - if line.amount_cashback > 0: - sales_price += line.amount_cashback purchase_price = line.purchase_price if line.purchase_tax_id.price_include: - purchase_price = line.purchase_price / 1.11 + purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) + + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -252,7 +253,7 @@ class SaleOrderLine(models.Model): def _compute_cashback_brand(self): for line in self: - line.amount_cashback = 0 + line.amount_cashback = 0 if not line.product_id: continue @@ -261,8 +262,18 @@ class SaleOrderLine(models.Model): if cashback_percent <= 0: continue - price, taxes, vendor_id = self._get_purchase_price(line.product_id) - line.amount_cashback = price * cashback_percent + price, taxes, vendor = self._get_purchase_price(line.product_id) + + price_tax_excl = price + + if taxes: + tax = self.env['account.tax'].browse(taxes) + if tax.price_include: + price_tax_excl = price / (1 + (tax.amount / 100)) + else: + price_tax_excl = price + + line.amount_cashback = price_tax_excl * cashback_percent # @api.onchange('vendor_id') # def onchange_vendor_id(self): -- cgit v1.2.3 From 4560970a9bdfd9fab483019f24d78cfe78330e32 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 30 Jan 2026 14:20:18 +0700 Subject: fix cashback --- indoteknik_custom/models/sale_order_line.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index c9e75fc7..d36c03e5 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -165,7 +165,10 @@ class SaleOrderLine(models.Model): purchase_price = line.purchase_price if line.purchase_tax_id.price_include: - purchase_price = line.purchase_price / 1.11 + purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) + + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -187,7 +190,7 @@ class SaleOrderLine(models.Model): purchase_price = line.purchase_price if line.purchase_tax_id and line.purchase_tax_id.price_include: - purchase_price = line.purchase_price / 1.11 + purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) purchase_price = purchase_price * line.product_uom_qty @@ -245,7 +248,7 @@ class SaleOrderLine(models.Model): purchase_price = line.purchase_price if line.purchase_tax_id.price_include: - purchase_price = line.purchase_price / 1.11 + purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price -- cgit v1.2.3 From 4ac8b06616a0dce80029e1063078b31b6100084e Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 30 Jan 2026 15:52:21 +0700 Subject: refund kebutuhan BA dan cahsback --- indoteknik_custom/models/refund_sale_order.py | 53 ++++++++++++++++++++------- indoteknik_custom/models/sale_order_line.py | 42 ++++++++++----------- indoteknik_custom/views/sale_order.xml | 2 +- indoteknik_custom/views/x_manufactures.xml | 2 +- 4 files changed, 63 insertions(+), 36 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 1c482619..c3b7a356 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -62,7 +62,8 @@ class RefundSaleOrder(models.Model): ('uang', 'Refund Lebih Bayar'), ('retur_half', 'Refund Retur Sebagian'), ('retur', 'Refund Retur Full'), - ('salah_transfer', 'Salah Transfer') + ('salah_transfer', 'Salah Transfer'), + ('berita_acara', 'Kebutuhan Berita Acara') ], string='Refund Type', required=True) tukar_guling_ids = fields.One2many( @@ -251,7 +252,7 @@ class RefundSaleOrder(models.Model): invoice_ids_data = vals.get('invoice_ids', []) invoice_ids = invoice_ids_data[0][2] if invoice_ids_data and invoice_ids_data[0][0] == 6 else [] invoices = self.env['account.move'].browse(invoice_ids) - if invoice_ids and refund_type and refund_type not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: + if invoice_ids and refund_type and refund_type not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half', 'berita_acara']: raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur jika ada invoice") if not invoice_ids and refund_type and refund_type in ['uang', 'barang_kosong_sebagian', 'retur_half']: @@ -434,13 +435,17 @@ class RefundSaleOrder(models.Model): total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0 vals['total_invoice'] = total_invoice amount_refund = vals.get('amount_refund', 0.0) - can_refund = sisa_uang_masuk - total_invoice - - if amount_refund > can_refund or can_refund == 0.0: - raise ValidationError( - _("Maksimal refund yang bisa dilakukan adalah sebesar %s. " - "Silakan sesuaikan jumlah refund.") % (can_refund) - ) + can_refund = 0.0 + if refund_type == 'berita_acara': + can_refund = sisa_uang_masuk + else: + can_refund = sisa_uang_masuk - total_invoice + if refund_type != 'berita_acara': + if amount_refund > can_refund or can_refund == 0.0: + raise ValidationError( + _("Maksimal refund yang bisa dilakukan adalah sebesar %s. " + "Silakan sesuaikan jumlah refund.") % (can_refund) + ) if amount_refund <= 0.00: raise ValidationError('Total Refund harus lebih dari 0 jika ingin mengajukan refund') @@ -451,7 +456,11 @@ class RefundSaleOrder(models.Model): raise UserError("❌ Refund multi SO hanya bisa 1 kali.") vals['remaining_refundable'] = 0.0 elif so_ids and len(so_ids) == 1 and refund_type != 'salah_transfer': - remaining = vals['uang_masuk'] - amount_refund + remaining = 0.0 + if refund_type == 'berita_acara': + vals['remaining_refundable'] = vals['uang_masuk'] - amount_refund + else: + vals['remaining_refundable'] = remaining if remaining < 0: raise ValidationError("❌ Tidak ada sisa transaksi untuk di-refund di SO ini. Semua dana sudah dikembalikan.") vals['remaining_refundable'] = remaining @@ -548,10 +557,28 @@ class RefundSaleOrder(models.Model): if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids', 'amount_refund']): total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) vals['total_invoice'] = total_invoice - uang_masuk = rec.uang_masuk - can_refund = uang_masuk - total_invoice - + uang_masuk = vals.get('uang_masuk', rec.uang_masuk) amount_refund = vals.get('amount_refund', rec.amount_refund) + can_refund = 0.0 + total_refunded = 0.0 + + if refund_type == 'berita_acara': + can_refund = uang_masuk + remaining = uang_masuk - amount_refund + else: + can_refund = uang_masuk - total_invoice + + existing_refunds = self.search([ + ('sale_order_ids', 'in', so_ids), + ('id', '!=', rec.id) + ]) + total_refunded = sum(existing_refunds.mapped('amount_refund')) + + if existing_refunds: + remaining = uang_masuk - total_refunded + else: + remaining = uang_masuk - amount_refund + if amount_refund > can_refund: raise ValidationError( diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index d36c03e5..55bea22c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -167,8 +167,8 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) - if line.amount_cashback > 0: - purchase_price = purchase_price - line.amount_cashback + # if line.amount_cashback > 0: + # purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -221,8 +221,8 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) - if line.amount_cashback > 0: - purchase_price = purchase_price - line.amount_cashback + # if line.amount_cashback > 0: + # purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -254,29 +254,29 @@ class SaleOrderLine(models.Model): margin_per_item = sales_price - purchase_price line.item_before_margin = margin_per_item - def _compute_cashback_brand(self): - for line in self: - line.amount_cashback = 0 + # def _compute_cashback_brand(self): + # for line in self: + # line.amount_cashback = 0 - if not line.product_id: - continue + # if not line.product_id: + # continue - cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 - if cashback_percent <= 0: - continue + # cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 + # if cashback_percent <= 0: + # continue - price, taxes, vendor = self._get_purchase_price(line.product_id) + # price, taxes, vendor = self._get_purchase_price(line.product_id) - price_tax_excl = price + # price_tax_excl = price - if taxes: - tax = self.env['account.tax'].browse(taxes) - if tax.price_include: - price_tax_excl = price / (1 + (tax.amount / 100)) - else: - price_tax_excl = price + # if taxes: + # tax = self.env['account.tax'].browse(taxes) + # if tax.price_include: + # price_tax_excl = price / (1 + (tax.amount / 100)) + # else: + # price_tax_excl = price - line.amount_cashback = price_tax_excl * cashback_percent + # line.amount_cashback = price_tax_excl * cashback_percent # @api.onchange('vendor_id') # def onchange_vendor_id(self): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index c3df92ec..7a517ca7 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -302,7 +302,7 @@ ] } "/> - + - + -- cgit v1.2.3 From 48e48a61a6fc0addcc1e0c3590ca8582abe66a6a Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Fri, 30 Jan 2026 18:19:30 +0700 Subject: refund kebutuhan BA dan cahsback --- indoteknik_custom/models/refund_sale_order.py | 6 +--- indoteknik_custom/models/sale_order_line.py | 48 +++++++++++++++------------ indoteknik_custom/views/sale_order.xml | 2 +- indoteknik_custom/views/x_manufactures.xml | 2 +- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index c3b7a356..7a219130 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -456,11 +456,7 @@ class RefundSaleOrder(models.Model): raise UserError("❌ Refund multi SO hanya bisa 1 kali.") vals['remaining_refundable'] = 0.0 elif so_ids and len(so_ids) == 1 and refund_type != 'salah_transfer': - remaining = 0.0 - if refund_type == 'berita_acara': - vals['remaining_refundable'] = vals['uang_masuk'] - amount_refund - else: - vals['remaining_refundable'] = remaining + remaining = vals['uang_masuk'] - amount_refund if remaining < 0: raise ValidationError("❌ Tidak ada sisa transaksi untuk di-refund di SO ini. Semua dana sudah dikembalikan.") vals['remaining_refundable'] = remaining diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 55bea22c..270fc842 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -167,8 +167,8 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) - # if line.amount_cashback > 0: - # purchase_price = purchase_price - line.amount_cashback + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -192,6 +192,9 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id and line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback + purchase_price = purchase_price * line.product_uom_qty margin_before = sales_price - purchase_price @@ -221,8 +224,8 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) - # if line.amount_cashback > 0: - # purchase_price = purchase_price - line.amount_cashback + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price @@ -250,33 +253,36 @@ class SaleOrderLine(models.Model): if line.purchase_tax_id.price_include: purchase_price = line.purchase_price / (1 + (line.purchase_tax_id.amount / 100)) + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback + purchase_price = purchase_price * line.product_uom_qty margin_per_item = sales_price - purchase_price line.item_before_margin = margin_per_item - # def _compute_cashback_brand(self): - # for line in self: - # line.amount_cashback = 0 + def _compute_cashback_brand(self): + for line in self: + line.amount_cashback = 0 - # if not line.product_id: - # continue + if not line.product_id: + continue - # cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 - # if cashback_percent <= 0: - # continue + cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 + if cashback_percent <= 0: + continue - # price, taxes, vendor = self._get_purchase_price(line.product_id) + price, taxes, vendor = self._get_purchase_price(line.product_id) - # price_tax_excl = price + price_tax_excl = price - # if taxes: - # tax = self.env['account.tax'].browse(taxes) - # if tax.price_include: - # price_tax_excl = price / (1 + (tax.amount / 100)) - # else: - # price_tax_excl = price + if taxes: + tax = self.env['account.tax'].browse(taxes) + if tax.price_include: + price_tax_excl = price / (1 + (tax.amount / 100)) + else: + price_tax_excl = price - # line.amount_cashback = price_tax_excl * cashback_percent + line.amount_cashback = price_tax_excl * cashback_percent # @api.onchange('vendor_id') # def onchange_vendor_id(self): diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 7a517ca7..c3df92ec 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -302,7 +302,7 @@ ] } "/> - + - + -- cgit v1.2.3 From 04093dbd490ef94a19aa2df69793e8eeb48831c5 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 11:24:09 +0700 Subject: fix date order cashback start februari --- indoteknik_custom/models/refund_sale_order.py | 2 +- indoteknik_custom/models/sale_order_line.py | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 7a219130..7ce347a8 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -540,7 +540,7 @@ class RefundSaleOrder(models.Model): else: invoice_ids = rec.invoice_ids.ids - if invoice_ids and vals.get('refund_type', rec.refund_type) not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half', 'retur']: + if invoice_ids and vals.get('refund_type', rec.refund_type) not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half', 'retur', 'berita_acara']: raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur jika ada invoice") if not invoice_ids and vals.get('refund_type', rec.refund_type) in ['uang', 'barang_kosong_sebagian', 'retur_half']: diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 270fc842..dd44f84a 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -261,17 +261,25 @@ class SaleOrderLine(models.Model): line.item_before_margin = margin_per_item def _compute_cashback_brand(self): + start_date = datetime(2026, 2, 1, 0, 0, 0) for line in self: line.amount_cashback = 0 if not line.product_id: continue + if line.order_id.date_order < start_date: + continue + + price, taxes, vendor_id = self._get_purchase_price(line.product_id) + cashback_percent = line.product_id.x_manufacture.cashback_percent or 0 if cashback_percent <= 0: continue - price, taxes, vendor = self._get_purchase_price(line.product_id) + + if line.vendor_id.id != 5571: + continue price_tax_excl = price -- cgit v1.2.3 From d43b0c4621421fcfb1afe4724e13d2604570e1e6 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 13:02:55 +0700 Subject: fix margin po --- indoteknik_custom/models/purchase_order_line.py | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 8c72887d..603a4ca2 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -23,6 +23,9 @@ class PurchaseOrderLine(models.Model): so_item_percent_margin = fields.Float( 'SO Margin%', compute='compute_item_margin', help="Total % Margin in Sales Order Header") + amount_cashback = fields.Float( + 'SO Margin%', compute='_compute_cashback_brand', + help="Total % Margin in Sales Order Header") delivery_amt_line = fields.Float('DeliveryAmtLine', compute='compute_delivery_amt_line') line_no = fields.Integer('No', default=0) qty_available = fields.Float('Qty Available', compute='_compute_qty_stock') @@ -373,6 +376,9 @@ class PurchaseOrderLine(models.Model): purchase_price = line.price_subtotal if order.delivery_amount > 0: purchase_price += line.delivery_amt_line + + if line.amount_cashback > 0: + purchase_price = purchase_price - line.amount_cashback # Hitung margin dan persentase margin real_item_margin = total_sales_price - purchase_price @@ -384,6 +390,46 @@ class PurchaseOrderLine(models.Model): sum_margin += real_item_margin + def _compute_cashback_brand(self): + start_date = datetime(2026, 2, 1, 0, 0, 0) + + for line in self: + line.amount_cashback = 0.0 + + product = line.product_id + order = line.order_id + + if not product or not order: + continue + + if order.partner_id.id != 5571: + continue + + sales_matches = self.env['purchase.order.sales.match'].search([ + ('purchase_order_id', '=', order.id), + ('product_id', '=', product.id) + ]) + + total_cashback = 0.0 + + for match in sales_matches: + so_line = match.sale_line_id + so_order = so_line.order_id + + if not so_order.date_order or so_order.date_order < start_date: + continue + + cashback_percent = brand.cashback_percent or 0.0 + if cashback_percent <= 0: + continue + sales_price = so_line.price_reduce_taxexcl * match.qty_so + + cashback = sales_price * cashback_percent + total_cashback += cashback + + line.amount_cashback = total_cashback + + def compute_delivery_amt_line(self): for line in self: if line.product_id.type == 'product': -- cgit v1.2.3 From fe3fb82fdd879c703d968cf09b09e6411e91100f Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 13:08:50 +0700 Subject: fix margin po --- indoteknik_custom/models/purchase_order_line.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 603a4ca2..76dcc09e 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -419,7 +419,7 @@ class PurchaseOrderLine(models.Model): if not so_order.date_order or so_order.date_order < start_date: continue - cashback_percent = brand.cashback_percent or 0.0 + cashback_percent = product.x_manufacture.cashback_percent or 0.0 if cashback_percent <= 0: continue sales_price = so_line.price_reduce_taxexcl * match.qty_so -- cgit v1.2.3 From b7cd9ffe12f0dbae9abba2fdac32417bd400e481 Mon Sep 17 00:00:00 2001 From: Mqdd Date: Mon, 2 Feb 2026 13:43:44 +0700 Subject: fix vcm picking wrong receipt --- indoteknik_custom/models/tukar_guling_po.py | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index ae58d509..1ee10679 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -582,7 +582,23 @@ class TukarGulingPO(models.Model): ('group_id', '=', group.id), ('state', '=', 'done') ]) - bu_inputs = po_pickings.filtered(lambda p: p.picking_type_id.id == 28) + + product_ids = set(record.line_ids.mapped("product_id").ids) + + _logger.info("TG product_ids: %s", product_ids) + + def _get_moves(picking): + return picking.move_ids_without_package if picking.move_ids_without_package else picking.move_lines + + bu_inputs = po_pickings.filtered( + lambda p: p.picking_type_id.id == 28 and any( + m.product_id.id in product_ids + for m in _get_moves(p) + ) + ) + + _logger.info("BU INPUT dengan product sama: %s", bu_inputs.mapped("name")) + bu_puts = po_pickings.filtered(lambda p: p.picking_type_id.id == 75) else: raise UserError("Group ID tidak ditemukan pada BU Operations.") @@ -711,12 +727,26 @@ class TukarGulingPO(models.Model): # Ambil pasangannya di BU INPUT (asumsi urutan sejajar) sorted_bu_puts = sorted(bu_puts, key=lambda p: p.name) + # sorted_bu_inputs = sorted(bu_inputs, key=lambda p: p.name) + + # if bu_put_index >= len(sorted_bu_inputs): + # raise UserError("Tidak ditemukan pasangan BU INPUT untuk BU PUT yang dipilih.") + + # paired = [(sorted_bu_puts[bu_put_index], sorted_bu_inputs[bu_put_index])] sorted_bu_inputs = sorted(bu_inputs, key=lambda p: p.name) - if bu_put_index >= len(sorted_bu_inputs): - raise UserError("Tidak ditemukan pasangan BU INPUT untuk BU PUT yang dipilih.") + if not sorted_bu_inputs: + raise UserError( + "Tidak ditemukan BU INPUT yang memiliki product TG." + ) - paired = [(sorted_bu_puts[bu_put_index], sorted_bu_inputs[bu_put_index])] + paired = [(record.operations, sorted_bu_inputs[0])] + + _logger.info( + "🔗 Pairing BU PUT %s dengan BU INPUT %s", + record.operations.name, + sorted_bu_inputs[0].name + ) for bu_put, bu_input in paired: vrt = _create_return_from_picking(bu_put, bu_put_qty_map) -- cgit v1.2.3 From 8b28af52afe07363209601a1ad1cb90b7778d1d8 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 14:48:34 +0700 Subject: fix margin po 2 --- indoteknik_custom/models/purchase_order.py | 13 +++++++++++++ indoteknik_custom/models/refund_sale_order.py | 6 +++--- indoteknik_custom/models/sale_order.py | 2 +- indoteknik_custom/views/purchase_order.xml | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 35fa79a8..a1e92e10 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,6 +53,9 @@ class PurchaseOrder(models.Model): total_so_percent_margin = fields.Float( 'SO Margin%', compute='compute_total_margin', help="Total % Margin in Sales Order Header") + amount_cashback = fields.Float( + 'Cashback', compute='compute_total_margin', + help="Total Cashback brand Altama") amount_total_without_service = fields.Float('AmtTotalWithoutService', compute='compute_amt_total_without_service') summary_qty_po = fields.Float('Total Qty', compute='_compute_summary_qty') summary_qty_receipt = fields.Float('Summary Qty Receipt', compute='_compute_summary_qty') @@ -1418,6 +1421,14 @@ class PurchaseOrder(models.Model): purchase_price += line.delivery_amt_line if line.order_id.delivery_amt > 0: purchase_price += line.order_id.delivery_amt + + cashback_amount = 0.0 + if self.partner_id.id == 5571: + cashback_percent = line.product_id.x_manufacture.cashback_percent or 0.0 + if cashback_percent > 0: + cashback_amount = purchase_price * cashback_percent + purchase_price -= cashback_amount + real_item_margin = sales_price - purchase_price sum_margin += real_item_margin @@ -1426,11 +1437,13 @@ class PurchaseOrder(models.Model): self.total_so_percent_margin = round((sum_so_margin / sum_sales_price), 2) * 100 self.total_margin = sum_margin self.total_percent_margin = round((sum_margin / sum_sales_price), 2) * 100 + self.amount_cashback = cashback_amount else: self.total_margin = 0 self.total_percent_margin = 0 self.total_so_margin = 0 self.total_so_percent_margin = 0 + self.amount_cashback = 0 def compute_total_margin_from_apo(self): sum_so_margin = sum_sales_price = sum_margin = 0 diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 7ce347a8..d6aa1ad2 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -243,7 +243,7 @@ class RefundSaleOrder(models.Model): ) invoices = sale_orders.mapped('invoice_ids').filtered( - lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.payment_state == 'paid' + lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.state == 'posted' ) if invoices: vals['invoice_ids'] = [(6, 0, invoices.ids)] @@ -497,7 +497,7 @@ class RefundSaleOrder(models.Model): valid_invoices = sale_orders.mapped('invoice_ids').filtered( - lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.payment_state == 'paid' + lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.state == 'posted' ) vals['invoice_ids'] = [(6, 0, valid_invoices.ids)] vals['ongkir'] = sum(so.delivery_amt or 0.0 for so in sale_orders) @@ -733,7 +733,7 @@ class RefundSaleOrder(models.Model): for so in self.sale_order_ids: self.ongkir += so.delivery_amt or 0.0 valid_invoices = so.invoice_ids.filtered( - lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.payment_state == 'paid' + lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.state == 'posted' ) all_invoices |= valid_invoices total_invoice += sum(valid_invoices.mapped('amount_total_signed')) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 469509d4..a4bc2309 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -3438,7 +3438,7 @@ class SaleOrder(models.Model): def button_refund(self): self.ensure_one() - invoice_ids = self.invoice_ids.filtered(lambda inv: inv.payment_state == 'paid') + invoice_ids = self.invoice_ids.filtered(lambda inv: inv.state == 'posted') moves = self.env['account.move'].search([ ('sale_id', '=', self.id), diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index 16b8bd44..59e317d2 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -105,6 +105,7 @@ + -- cgit v1.2.3