From 9496bae642b86438f0dcef1595255e2f01384040 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 23 Jan 2026 09:40:35 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 35fa79a8..50418fc9 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1086,12 +1086,12 @@ class PurchaseOrder(models.Model): if self.order_sales_match_line: if self.total_percent_margin <= 15.0: raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") - else: - low_margin_match_so = self.order_sales_match_line.filtered( - lambda match: match.so_header_margin <= 15.0 - ) - if low_margin_match_so: - raise UserError("Approval Pimpinan diperlukan jika pada PO Line yang Matches SO item memiliki header margin SO <= 15%") + # else: + # low_margin_match_so = self.order_sales_match_line.filtered( + # lambda match: match.so_header_margin <= 15.0 + # ) + # if low_margin_match_so: + # raise UserError("Approval Pimpinan diperlukan jika pada PO Line yang Matches SO item memiliki header margin SO <= 15%") # else: # is_po_manual = '/A/' not in self.name and '/MO/' not in self.name # if is_po_manual: -- cgit v1.2.3 From e700b4017f5f33564386dec52f3633b84a7e35a8 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 23 Jan 2026 09:43:28 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 50418fc9..2154fb8c 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1079,14 +1079,14 @@ class PurchaseOrder(models.Model): ) % order.name) def button_confirm(self): - if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan - if '/PJ/' in self.name: - price_change_detected = any(line.price_unit_before for line in self.order_line) - if price_change_detected: - if self.order_sales_match_line: - if self.total_percent_margin <= 15.0: - raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") - # else: + # if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan + # if '/PJ/' in self.name: + # price_change_detected = any(line.price_unit_before for line in self.order_line) + # if price_change_detected: + # if self.order_sales_match_line: + # if self.total_percent_margin <= 15.0: + # raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + # # else: # low_margin_match_so = self.order_sales_match_line.filtered( # lambda match: match.so_header_margin <= 15.0 # ) -- cgit v1.2.3 From f2fbd1496a5ef1f86df794f69c8d0430f7caed63 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 23 Jan 2026 09:57:46 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 2154fb8c..e16c8d61 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1079,24 +1079,13 @@ class PurchaseOrder(models.Model): ) % order.name) def button_confirm(self): - # if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan - # if '/PJ/' in self.name: - # price_change_detected = any(line.price_unit_before for line in self.order_line) - # if price_change_detected: - # if self.order_sales_match_line: - # if self.total_percent_margin <= 15.0: - # raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") - # # else: - # low_margin_match_so = self.order_sales_match_line.filtered( - # lambda match: match.so_header_margin <= 15.0 - # ) - # if low_margin_match_so: - # raise UserError("Approval Pimpinan diperlukan jika pada PO Line yang Matches SO item memiliki header margin SO <= 15%") - # else: - # is_po_manual = '/A/' not in self.name and '/MO/' not in self.name - # if is_po_manual: - # if not self.order_sales_match_line: - # raise UserError("Tidak ada matches SO, Approval Pimpinan diperlukan.") + if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan + if '/PJ/' in self.name: + price_change_detected = any(line.price_unit_before for line in self.order_line) + if price_change_detected: + if self.order_sales_match_line: + if self.total_percent_margin <= 15.0: + raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") self._check_assets_note() # self._check_payment_term() # check payment term -- 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 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'indoteknik_custom/models/purchase_order.py') 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 -- cgit v1.2.3 From 5118ff0549de5bea4e83b31da2c2347f227c488a Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 14:55:02 +0700 Subject: pusing margin po --- indoteknik_custom/models/purchase_order.py | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index a1e92e10..35fa79a8 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,9 +53,6 @@ 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') @@ -1421,14 +1418,6 @@ 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 @@ -1437,13 +1426,11 @@ 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 -- cgit v1.2.3 From 37ccff02eb47b50ca6d23e4cd027155381c53947 Mon Sep 17 00:00:00 2001 From: HafidBuroiroh Date: Mon, 2 Feb 2026 16:59:12 +0700 Subject: coba margin po last --- indoteknik_custom/models/purchase_order.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 35fa79a8..60802649 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,19 +1421,29 @@ 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 - if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0: + if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0 and cashback_amount != 0: self.total_so_margin = sum_so_margin 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 @@ -1469,6 +1482,13 @@ class PurchaseOrder(models.Model): purchase_price += (po_line.delivery_amt_line / po_line.product_qty) * qty_po if line.purchase_order_id.delivery_amt > 0: purchase_price += line.purchase_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 @@ -1479,9 +1499,11 @@ 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 = self.total_percent_margin = 0 self.total_so_margin = self.total_so_percent_margin = 0 + self.amount_cashback = 0 def compute_amt_total_without_service(self): -- cgit v1.2.3 From 4fa6b57647f7f53573bd83d9dd4f0292ab955e1a Mon Sep 17 00:00:00 2001 From: Mqdd Date: Tue, 3 Feb 2026 11:41:35 +0700 Subject: fix margin PO --- indoteknik_custom/models/purchase_order.py | 51 +++++++++++++++++++----------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6b6e6aa2..820f8091 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -53,9 +53,7 @@ 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_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') @@ -1086,9 +1084,19 @@ class PurchaseOrder(models.Model): if '/PJ/' in self.name: price_change_detected = any(line.price_unit_before for line in self.order_line) if price_change_detected: - if self.order_sales_match_line: - if self.total_percent_margin <= 15.0: - raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + if self.total_percent_margin <= 15.0: + raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + else: + low_margin_match_so = self.order_sales_match_line.filtered( + lambda match: match.so_header_margin <= 15.0 + ) + if low_margin_match_so: + raise UserError("Approval Pimpinan diperlukan jika pada PO Line yang Matches SO item memiliki header margin SO <= 15%") + # else: + # is_po_manual = '/A/' not in self.name and '/MO/' not in self.name + # if is_po_manual: + # if not self.order_sales_match_line: + # raise UserError("Tidak ada matches SO, Approval Pimpinan diperlukan.") self._check_assets_note() # self._check_payment_term() # check payment term @@ -1410,18 +1418,25 @@ class PurchaseOrder(models.Model): purchase_price += line.delivery_amt_line if line.order_id.delivery_amt > 0: purchase_price += line.order_id.delivery_amt + real_item_margin = sales_price - purchase_price + sum_margin += real_item_margin - cashback_amount = 0.0 + cashback_amount = 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 + # line.amount_cashback = cashback_amount - if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0 and cashback_amount != 0: + if sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0: + self.total_so_margin = sum_so_margin + 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 = 0 + elif self.partner_id.id == 5571 and sum_so_margin != 0 and sum_sales_price != 0 and sum_margin != 0 and cashback_amount != 0: self.total_so_margin = sum_so_margin self.total_so_percent_margin = round((sum_so_margin / sum_sales_price), 2) * 100 self.total_margin = sum_margin @@ -1435,7 +1450,7 @@ class PurchaseOrder(models.Model): self.amount_cashback = 0 def compute_total_margin_from_apo(self): - sum_so_margin = sum_sales_price = sum_margin = 0 + sum_so_margin = sum_sales_price = sum_margin = cashback_amount = 0 for line in self.order_sales_match_line: po_line = self.env['purchase.order.line'].search([ ('product_id', '=', line.product_id.id), @@ -1471,17 +1486,17 @@ class PurchaseOrder(models.Model): purchase_price += (po_line.delivery_amt_line / po_line.product_qty) * qty_po if line.purchase_order_id.delivery_amt > 0: purchase_price += line.purchase_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 + + 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 + self.amount_cashback = cashback_amount # Akumulasi hasil akhir if sum_sales_price != 0: self.total_so_margin = sum_so_margin -- cgit v1.2.3 From 9da91430c095af5d46e6821de82a93b30ce42a26 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 4 Feb 2026 13:19:37 +0700 Subject: off confirm --- indoteknik_custom/models/purchase_order.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index e16c8d61..cb6e70b1 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1079,13 +1079,13 @@ class PurchaseOrder(models.Model): ) % order.name) def button_confirm(self): - if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan - if '/PJ/' in self.name: - price_change_detected = any(line.price_unit_before for line in self.order_line) - if price_change_detected: - if self.order_sales_match_line: - if self.total_percent_margin <= 15.0: - raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + # if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan + # if '/PJ/' in self.name: + # price_change_detected = any(line.price_unit_before for line in self.order_line) + # if price_change_detected: + # if self.order_sales_match_line: + # if self.total_percent_margin <= 15.0: + # raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") self._check_assets_note() # self._check_payment_term() # check payment term -- cgit v1.2.3 From 983fa2ec6b13f4005f4e27e7b7860503c4823f8e Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 4 Feb 2026 15:45:56 +0700 Subject: on confirm --- indoteknik_custom/models/purchase_order.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 6c3e4185..a066d90b 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1080,13 +1080,13 @@ class PurchaseOrder(models.Model): ) % order.name) def button_confirm(self): - # if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan - # if '/PJ/' in self.name: - # price_change_detected = any(line.price_unit_before for line in self.order_line) - # if price_change_detected: - # if self.order_sales_match_line: - # if self.total_percent_margin <= 15.0: - # raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") + if self.env.user.id != 7 and not self.env.user.is_leader: # Pimpinan + if '/PJ/' in self.name: + price_change_detected = any(line.price_unit_before for line in self.order_line) + if price_change_detected: + if self.order_sales_match_line: + if self.total_percent_margin <= 25.0: + raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") self._check_assets_note() # self._check_payment_term() # check payment term -- cgit v1.2.3 From 26713fca51335e68f737c171b8de918c8192ea8d Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Wed, 4 Feb 2026 15:55:21 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index a066d90b..b3ecca56 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1085,7 +1085,7 @@ class PurchaseOrder(models.Model): price_change_detected = any(line.price_unit_before for line in self.order_line) if price_change_detected: if self.order_sales_match_line: - if self.total_percent_margin <= 25.0: + if self.total_percent_margin <= 15.0: raise UserError("Approval Pimpinan diperlukan jika terdapat perubahan Unit Price pada PO Line dan Memiliki Margin <= 15%") self._check_assets_note() -- cgit v1.2.3 From 1112947139e69732589352359105e7602d6539b2 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 24 Feb 2026 12:40:04 +0700 Subject: (andri) fix error singleton create bill po karena payment term dp 30 multi line --- indoteknik_custom/models/purchase_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b3ecca56..c3ab71aa 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -632,7 +632,8 @@ class PurchaseOrder(models.Model): date_done = self.date_approve - day_extension = int(self.payment_term_id.line_ids.days) + # day_extension = int(self.payment_term_id.line_ids.days) + day_extension = int(max(self.payment_term_id.line_ids.mapped('days'))) payment_schedule = date_done + timedelta(days=day_extension) if payment_schedule.weekday() == 0: -- cgit v1.2.3 From 316b8257845d0df10153fa7e5e294a699ad17c56 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Tue, 24 Feb 2026 13:20:33 +0700 Subject: push --- indoteknik_custom/models/purchase_order.py | 299 +++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b3ecca56..dd0c5cd5 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -8,6 +8,8 @@ import io import base64 from odoo.tools import lazy_property import socket +import requests +import json try: from odoo.tools.misc import xlsxwriter @@ -125,7 +127,304 @@ class PurchaseOrder(models.Model): ) overseas_po = fields.Boolean(string='PO Luar Negeri?', tracking=3, help='Centang jika PO untuk pembelian luar negeri') + order_altama_id = fields.Integer('Req Order Altama', copy=False) + soo_number = fields.Char('SOO Number', copy=False) + soo_price = fields.Float('SOO Price', copy=False) + soo_discount = fields.Float('SOO Discount', copy=False) + soo_tax = fields.Float('SOO Tax', copy=False) + + def _get_altama_token(self, source='auto'): + ICP = self.env['ir.config_parameter'].sudo() + TokenLog = self.env['token.log'].sudo() + + token_url = ICP.get_param('token.adempiere.altama') + client_id = ICP.get_param('client.adempiere.altama') + client_secret = ICP.get_param('secret_key.adempiere.altama') + + active_token = TokenLog.search([ + ('is_active', '=', True), + ('token_from', '=', 'Adempiere Altama'), + ('expires_at', '>', datetime.utcnow()), + ], limit=1, order='id desc') + + if active_token: + return active_token.token + + headers = { + "Authorization": "Basic " + base64.b64encode(f"{client_id}:{client_secret}".encode()).decode(), + "Content-Type": "application/x-www-form-urlencoded", + } + data = {"grant_type": "client_credentials"} + + response = requests.post(token_url, data=data, headers=headers, timeout=15) + if response.status_code == 200: + result = response.json() + token = result.get("access_token") + expires_in = result.get("expires_in", 3600) + expiry_time = datetime.utcnow() + timedelta(seconds=expires_in - 60) + + TokenLog.search([ + ('token_from', '=', 'Adempiere Altama'), + ('is_active', '=', True), + ]).write({'is_active': False}) + + TokenLog.create({ + 'token': token, + 'expires_at': expiry_time, + 'is_active': True, + 'created_by': self.env.user.id if self.env.user else None, + 'source': source, + 'token_from': 'Adempiere Altama', + }) + + return token + + else: + raise Exception(f"Gagal ambil token: {response.status_code} - {response.text}") + + def action_create_order_altama(self): + ICP = self.env['ir.config_parameter'].sudo() + for order in self: + try: + token = self._get_altama_token(source='manual') + url = ICP.get_param('endpoint.create.order.adempiere.altama') + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json", + } + + payload = { + "date_po": order.date_approve.strftime("%Y%m%d%H%M%S"), + "no_po": order.name, + "details": [ + { + "item_code": line.product_id.default_code or "", + "price": line.price_unit, + "qty": line.product_qty, + } + for line in order.order_line + ], + } + + response = requests.post(url, json=payload, headers=headers, timeout=20) + + try: + result = response.json() + except json.JSONDecodeError: + raise Exception(f"Response bukan JSON valid: {response.text}") + + if response.status_code == 200 and result.get("code") == "00": + contents = result.get("contents", {}) + if isinstance(contents, dict): + order.order_altama_id = contents.get("req_id") + else: + order.order_altama_id = contents.get("req_id") + + elif response.status_code == 404: + raise Exception("URL endpoint gak ditemukan (404). Pastikan path-nya benar di Altama API.") + elif response.status_code == 401: + token = self._get_altama_token(source='auto') + headers["Authorization"] = f"Bearer {token}" + response = requests.post(url, json=payload, headers=headers, timeout=20) + elif response.status_code not in (200, 201): + raise Exception(f"Gagal kirim ke Altama: {response.status_code} - {response.text}") + + self.message_post(body=f"✅ PO berhasil dikirim ke Altama!\nResponse: {json.dumps(result, indent=2)}") + + except Exception as e: + self.message_post(body=f"❌ Gagal kirim ke Altama:
{str(e)}
") + + + def action_get_order_altama(self): + ICP = self.env['ir.config_parameter'].sudo() + for order in self: + try: + # ============================ + # Get Token + # ============================ + token = self._get_altama_token(source='manual') + + url = ICP.get_param('endpoint.get.order.adempiere.altama') + if not url: + raise Exception("Parameter 'endpoint.adempiere.altama' belum diset di System Parameters.") + + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json", + } + + params = { + "orderreq_id": order.order_altama_id or 0, + } + + # ============================ + # Request ke API + # ============================ + response = requests.get(url, headers=headers, params=params, timeout=20) + + if response.status_code == 401: + token = self._get_altama_token(source='auto') + headers["Authorization"] = f"Bearer {token}" + response = requests.get(url, headers=headers, params=params, timeout=20) + + if response.status_code not in (200, 201): + raise Exception(f"Gagal ambil data dari Altama: {response.status_code} - {response.text}") + + data = response.json() + + # ============================ + # Extract Data + # ============================ + contents_root = data.get("contents", {}) + contents_list = contents_root.get("contents", []) + + if not isinstance(contents_list, list): + raise Exception("Format data contents dari Altama tidak sesuai (expected list).") + + order.message_post( + body=f"✅ Berhasil ambil data dari Altama. Ditemukan {len(contents_list)} record." + ) + + # ===================================================== + # LOOP MAIN DATA + # ===================================================== + for item in contents_list: + + req_id = item.get("req_id") + no_po = item.get("no_po") + list_item_po = item.get("list_Item_po", []) + list_soo = item.get("list_soo", []) + + # ============================ + # Isi Data SOO Ke Order + # ============================ + soo_numbers = [s.get("no_soo") for s in list_soo if s.get("no_soo")] + unique_soo = list(set(soo_numbers)) + if len(unique_soo) == 1: + order.soo_number = unique_soo[0] + if not order.picking_ids.number_soo: + order.picking_ids[0].number_soo = unique_soo[0] + elif len(unique_soo) > 1: + order.soo_number = ", ".join(unique_soo) + if not order.picking_ids.number_soo: + order.picking_ids[0].number_soo = ", ".join(unique_soo) + else: + order.soo_number = False + + if list_soo: + first_soo = list_soo[0] + order.soo_price = first_soo.get("totalprice") + order.soo_discount = first_soo.get("diskon") + order.soo_tax = first_soo.get("ppn") + + order.order_altama_id = req_id + + # ============================ + # Update Order Lines + # ============================ + for item_line in list_item_po: + + line = order.order_line.filtered( + lambda l: l.product_id.default_code == item_line.get("item_code") + ) + + if line: + line.write({ + "description": item_line.get("description", ""), + "altama_ordered": item_line.get("qtyordered", 0), + "altama_delivered": item_line.get("qtydelivered", 0), + "altama_invoiced": item_line.get("qtyinvoiced", 0), + "docstatus_altama": item_line.get("docstatus", ""), + }) + + # ===================================================== + # BUILD HTML TABLES FOR CHATTER + # ===================================================== + + # ---- SOO TABLE ---- + soo_rows = "" + for s in list_soo: + soo_rows += f""" + + {s.get('no_soo')} + {s.get('totalprice')} + {s.get('diskon')} + {s.get('ppn')} + + """ + + soo_table = f""" + + + + + + + + + + + {soo_rows or ''} + +
SOO NumberTotal PriceDiskonPPN
Tidak ada data SOO
+ """ + + # ---- ITEM PO TABLE ---- + po_rows = "" + for l in list_item_po: + + desc = l.get("description") or "" + + # Flag: row error kalau description tidak mulai dengan SOO/ + is_error = desc and not desc.startswith("SOO/") + + # Style row merah + row_style = "color:red; font-weight:bold;" if is_error else "" + + po_rows += f""" + + {l.get('item_code')} + {desc} + {l.get('qtyordered')} + {l.get('qtydelivered')} + {l.get('qtyinvoiced')} + {l.get('docstatus')} + + """ + + + po_table = f""" + + + + + + + + + + + + + {po_rows or ''} + +
Item CodeDescriptionOrderedDeliveredInvoicedStatus
Tidak ada item PO
+ """ + + # ---- POST TO CHATTER ---- + order.message_post( + body=f""" + 📦 Data SOO
{soo_table} +

+ 📦 Data Item PO
{po_table} + """ + ) + + except Exception as e: + order.message_post( + body=f"❌ Gagal ambil data dari Altama:
{str(e)}
" + ) @staticmethod def is_local_env(): hostname = socket.gethostname().lower() -- cgit v1.2.3 From 09b1d9f475367b95759d6c7d466a48edf8ebac4e Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 24 Feb 2026 14:27:46 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index c3ab71aa..0afa5155 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -633,7 +633,7 @@ class PurchaseOrder(models.Model): date_done = self.date_approve # day_extension = int(self.payment_term_id.line_ids.days) - day_extension = int(max(self.payment_term_id.line_ids.mapped('days'))) + day_extension = int(max(self.payment_term_id.line_ids.mapped('days')), default=0) payment_schedule = date_done + timedelta(days=day_extension) if payment_schedule.weekday() == 0: -- cgit v1.2.3 From 75972376c64d133e4dcf8cb0808a60b36db07825 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Tue, 24 Feb 2026 14:33:34 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 0afa5155..6e09f3e9 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -633,7 +633,7 @@ class PurchaseOrder(models.Model): date_done = self.date_approve # day_extension = int(self.payment_term_id.line_ids.days) - day_extension = int(max(self.payment_term_id.line_ids.mapped('days')), default=0) + day_extension = int(max(self.payment_term_id.line_ids.mapped('days'), default=0)) payment_schedule = date_done + timedelta(days=day_extension) if payment_schedule.weekday() == 0: -- cgit v1.2.3 From 68040bdf60a35486ed1015421679310df742b74d Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Fri, 27 Feb 2026 09:36:15 +0700 Subject: push api altama odoo indo --- indoteknik_custom/models/purchase_order.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index b0fea18b..a345b96b 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -304,11 +304,15 @@ class PurchaseOrder(models.Model): if len(unique_soo) == 1: order.soo_number = unique_soo[0] if not order.picking_ids.number_soo: - order.picking_ids[0].number_soo = unique_soo[0] + # order.picking_ids[0].number_soo = unique_soo[0] + for picking in order.picking_ids: + picking.number_soo = unique_soo[0] elif len(unique_soo) > 1: order.soo_number = ", ".join(unique_soo) if not order.picking_ids.number_soo: - order.picking_ids[0].number_soo = ", ".join(unique_soo) + # order.picking_ids[0].number_soo = ", ".join(unique_soo) + for picking in order.picking_ids: + picking.number_soo = ", ".join(unique_soo) else: order.soo_number = False @@ -1442,6 +1446,9 @@ class PurchaseOrder(models.Model): send_email = True break + if self.partner_id.id == 5571 and not self.revisi_po: + self.action_create_order_altama() + if send_email: if self.is_local_env(): _logger.warning("📪 Local environment detected — skip sending email reminders.") @@ -1459,6 +1466,7 @@ class PurchaseOrder(models.Model): self.calculate_line_no() self.approve_by = self.env.user.id + # override date planned added with two days # leadtime = self.partner_id.leadtime # delta_time = current_time + timedelta(days=leadtime) -- cgit v1.2.3 From 1d61c5c2f29270d2d1e9c84e887e9c94416d9027 Mon Sep 17 00:00:00 2001 From: FIN-IT_AndriFP Date: Fri, 6 Mar 2026 11:03:10 +0700 Subject: fix --- indoteknik_custom/models/purchase_order.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indoteknik_custom/models/purchase_order.py') diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index a345b96b..244575ae 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -1446,8 +1446,8 @@ class PurchaseOrder(models.Model): send_email = True break - if self.partner_id.id == 5571 and not self.revisi_po: - self.action_create_order_altama() + # if self.partner_id.id == 5571 and not self.revisi_po: + # self.action_create_order_altama() if send_email: if self.is_local_env(): @@ -1484,6 +1484,8 @@ class PurchaseOrder(models.Model): # if len(self) == 1: # _logger.info("Redirecting ke BU") # return self.action_view_related_bu() + if self.partner_id.id == 5571 and not self.revisi_po: + self.action_create_order_altama() return res -- cgit v1.2.3