From 414b741f6fdd3ba37754db516c695231e3fbca6e Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Fri, 25 Jul 2025 09:22:20 +0700 Subject: hold refund --- indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/refund_sale_order.py | 8 ++++---- indoteknik_custom/models/sale_order.py | 2 +- indoteknik_custom/views/account_move.xml | 6 +++--- indoteknik_custom/views/sale_order.xml | 14 +++++++------- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 21afc26f..93c437af 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -170,6 +170,7 @@ 'views/public_holiday.xml', 'views/stock_inventory.xml', 'views/sale_order_delay.xml', + 'views/refund_sale_order.xml', ], 'demo': [], 'css': [], diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 11bfd07f..2a55f16d 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -175,7 +175,7 @@ class RefundSaleOrder(models.Model): if refund_type == 'retur_half' and not invoice_ids: raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk Retur Sebagian.") - total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total')) if invoice_ids else 0.0 + total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0 uang_masuk = vals.get('uang_masuk', 0.0) ongkir = vals.get('ongkir', 0.0) pengurangan = total_invoice + ongkir @@ -266,7 +266,7 @@ class RefundSaleOrder(models.Model): raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk retur sebagian.") if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids']): - total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total')) + total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) uang_masuk = vals.get('uang_masuk', rec.uang_masuk) ongkir = vals.get('ongkir', rec.ongkir) @@ -325,7 +325,7 @@ class RefundSaleOrder(models.Model): lambda inv: inv.move_type in ['out_invoice', 'out_refund'] and inv.state != 'cancel' ) all_invoices |= valid_invoices - total_invoice += sum(valid_invoices.mapped('amount_total')) + total_invoice += sum(valid_invoices.mapped('amount_total_signed')) self.invoice_ids = all_invoices @@ -464,7 +464,7 @@ class RefundSaleOrder(models.Model): if self.refund_type not in ['uang', 'barang_kosong']: self.refund_type = False - self.total_invoice = sum(self.invoice_ids.mapped('amount_total')) + self.total_invoice = sum(self.invoice_ids.mapped('amount_total_signed')) def action_ask_approval(self): for rec in self: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index febdaabd..c4de0d3a 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -3144,7 +3144,7 @@ class SaleOrder(models.Model): invoice_ids = self.mapped('invoice_ids').filtered(lambda inv: inv.state != 'cancel') delivery_total = sum(self.mapped('delivery_amt')) - total_invoice = sum(invoice_ids.mapped('amount_total')) + total_invoice = sum(invoice_ids.mapped('amount_total_signed')) return { 'type': 'ir.actions.act_window', diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml index 9b1c791b..ae944a4a 100644 --- a/indoteknik_custom/views/account_move.xml +++ b/indoteknik_custom/views/account_move.xml @@ -36,9 +36,9 @@ - - + + + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 5bcd7641..1a4726d6 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -35,13 +35,13 @@ string="UangMuka" type="action" attrs="{'invisible': [('approval_status', '!=', 'approved')]}"/> - +
- +
@@ -176,7 +176,7 @@ - + - + -- cgit v1.2.3 From b4fa8f4df995f946b642eda78ca5fc2b8badada2 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 28 Jul 2025 15:06:26 +0700 Subject: fixing journal --- indoteknik_custom/models/refund_sale_order.py | 32 ++++++++++++++++++++++----- indoteknik_custom/models/sale_order.py | 6 +++-- indoteknik_custom/views/refund_sale_order.xml | 6 ++--- indoteknik_custom/views/sale_order.xml | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 2a55f16d..80d66d8d 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -124,7 +124,7 @@ class RefundSaleOrder(models.Model): self.env.user.has_group('indoteknik_custom.group_role_fat') or self.env.user.id not in allowed_user_ids ): - raise UserError("❌ Hanya user Sales dan Finance yang boleh membuat refund.") + raise UserError("❌ Hanya Sales dan Finance yang boleh membuat refund.") if vals.get('name', 'New') == 'New': @@ -150,13 +150,18 @@ class RefundSaleOrder(models.Model): refund_type = vals.get('refund_type') 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 [] - if invoice_ids and refund_type and refund_type not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian jika ada invoice") - if not invoice_ids and refund_type and refund_type in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: + if not invoice_ids and refund_type and refund_type in ['uang', 'barang_kosong_sebagian', 'retur_half']: raise UserError("Refund type Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian Hanya Bisa dipilih Jika Ada Invoice") + if refund_type in ['barang_kosong', 'barang_kosong_sebagian'] and so_ids: + sale_orders = self.env['sale.order'].browse(so_ids) + zero_delivery_lines = sale_orders.mapped('order_line').filtered(lambda l: l.qty_delivered == 0) + if not zero_delivery_lines: + raise UserError("❌ Tidak ada barang yang Tidak Terikirim di Sales Order yang dipilih.") + if not so_ids and refund_type != 'lainnya': raise ValidationError("Jika tidak ada Sales Order yang dipilih, maka Tipe Refund hanya boleh 'Lainnya'.") @@ -180,6 +185,10 @@ class RefundSaleOrder(models.Model): ongkir = vals.get('ongkir', 0.0) pengurangan = total_invoice + ongkir + if refund_type == 'barang_kosong_sebagian' and so_ids: + sale_orders = self.env['sale.order'].browse(so_ids) + vals['uang_masuk'] = sum(sale_orders.mapped('amount_total')) + if uang_masuk > pengurangan: vals['amount_refund'] = uang_masuk - pengurangan else: @@ -229,8 +238,16 @@ class RefundSaleOrder(models.Model): refund_type = vals.get('refund_type', rec.refund_type) + if refund_type in ['barang_kosong', 'barang_kosong_sebagian'] and sale_orders: + zero_delivery_lines = sale_orders.mapped('order_line').filtered(lambda l: l.qty_delivered == 0) + if not zero_delivery_lines: + raise UserError("❌ Tidak ada barang yang Tidak Terikirim di Sales Order yang dipilih.") + if not so_ids and refund_type != 'lainnya': raise ValidationError("Jika tidak ada Sales Order yang dipilih, maka Tipe Refund hanya boleh 'Lainnya'.") + + if refund_type == 'barang_kosong_sebagian' and sale_orders: + vals['uang_masuk'] = sum(sale_orders.mapped('amount_total')) invoice_ids = vals.get('invoice_ids', False) @@ -248,7 +265,7 @@ class RefundSaleOrder(models.Model): if invoice_ids and vals.get('refund_type', rec.refund_type) not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian jika ada invoice") - if not invoice_ids and vals.get('refund_type', rec.refund_type) in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: + if not invoice_ids and vals.get('refund_type', rec.refund_type) in ['uang', 'barang_kosong_sebagian', 'retur_half']: raise UserError("Refund type Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian Hanya Bisa dipilih Jika Ada Invoice") if refund_type in ['retur', 'retur_half'] and so_ids: @@ -358,6 +375,9 @@ class RefundSaleOrder(models.Model): self.line_ids = line_vals + if self.refund_type == 'barang_kosong_sebagian' and self.sale_order_ids: + self.uang_masuk = sum(self.sale_order_ids.mapped('amount_total')) + sum(self.sale_order_ids.mapped('delivery_amt')) + elif self.refund_type in ['retur', 'retur_half'] and self.sale_order_ids: line_vals = [] StockPicking = self.env['stock.picking'] @@ -586,8 +606,8 @@ class RefundSaleOrder(models.Model): }) amount = refund.amount_refund - - second_account_id = 450 if has_invoice else 668 + # 450 Penerimaan Belum Teridentifikasi, 668 Penerimaan Belum Alokasi + second_account_id = 450 if refund.refund_type not in ['barang_kosong', 'barang_kosong_sebagian'] else 668 debit_line = { 'move_id': account_move.id, diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 4d0b1d7b..46dad6ff 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -3111,6 +3111,7 @@ class SaleOrder(models.Model): self.ensure_one() invoice_ids = self.invoice_ids.filtered(lambda inv: inv.state != 'cancel') + total_so = sum(self.mapped('amount_total')) return { 'name': 'Refund Sale Order', @@ -3121,7 +3122,7 @@ class SaleOrder(models.Model): 'context': { 'default_sale_order_ids': [(6, 0, [self.id])], 'default_invoice_ids': [(6, 0, invoice_ids.ids)], - 'default_uang_masuk': sum(invoice_ids.mapped('amount_total')) + (self.delivery_amt or 0.0) + 1000, + 'default_uang_masuk': total_so, 'default_ongkir': self.delivery_amt or 0.0, 'default_bank': '', # bisa isi default bank kalau mau 'default_account_name': '', @@ -3150,6 +3151,7 @@ class SaleOrder(models.Model): invoice_ids = self.mapped('invoice_ids').filtered(lambda inv: inv.state != 'cancel') delivery_total = sum(self.mapped('delivery_amt')) total_invoice = sum(invoice_ids.mapped('amount_total_signed')) + total_so = sum(self.mapped('amount_total')) return { 'type': 'ir.actions.act_window', @@ -3160,7 +3162,7 @@ class SaleOrder(models.Model): 'context': { 'default_sale_order_ids': [(6, 0, self.ids)], 'default_invoice_ids': [(6, 0, invoice_ids.ids)], - 'default_uang_masuk': total_invoice + delivery_total + 1000, + 'default_uang_masuk': total_so, 'default_ongkir': delivery_total, 'default_bank': '', 'default_account_name': '', diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index 4f791722..0c4eaa56 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -66,7 +66,7 @@ string="Journal Refund" type="object" class="oe_highlight" - attrs="{'invisible': ['|', ('status', 'not in', ['pengajuan3','refund']), ('journal_refund_state', '=', 'posted')]}"/> + attrs="{'invisible': [('journal_refund_state', '=', 'posted')]}"/> - - + + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 987303ba..08dcfbb7 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -40,7 +40,7 @@ type="object" string="Refund" class="btn-primary" - attrs="{'invisible': ['|', ('state', 'not in', ['sale', 'done']), ('has_refund', '=', True)]}" /> + attrs="{'invisible': [('has_refund', '=', 'True')]}" />
-- cgit v1.2.3 From 747075fb85372666b89d5ffd07a43664ecf169e1 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Mon, 4 Aug 2025 14:41:27 +0700 Subject: Fix problem --- indoteknik_custom/models/refund_sale_order.py | 20 ++++++++++++-------- indoteknik_custom/views/ir_sequence.xml | 2 +- indoteknik_custom/views/refund_sale_order.xml | 10 +++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 65e93ba4..077809e9 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -181,14 +181,17 @@ class RefundSaleOrder(models.Model): raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk Retur Sebagian.") total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0 - uang_masuk = vals.get('uang_masuk', 0.0) ongkir = vals.get('ongkir', 0.0) + vals['total_invoice'] = total_invoice pengurangan = total_invoice + ongkir if refund_type == 'barang_kosong_sebagian' and so_ids: sale_orders = self.env['sale.order'].browse(so_ids) vals['uang_masuk'] = sum(sale_orders.mapped('amount_total')) + + uang_masuk = vals.get('uang_masuk', 0.0) + if uang_masuk > pengurangan: vals['amount_refund'] = uang_masuk - pengurangan else: @@ -284,6 +287,7 @@ class RefundSaleOrder(models.Model): if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids']): total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) + vals['total_invoice'] = total_invoice uang_masuk = vals.get('uang_masuk', rec.uang_masuk) ongkir = vals.get('ongkir', rec.ongkir) @@ -296,10 +300,10 @@ class RefundSaleOrder(models.Model): return super().write(vals) - @api.depends('status_payment') + @api.depends('status_payment', 'status') def _compute_is_locked(self): for rec in self: - rec.is_locked = rec.status_payment in ['done', 'reject'] + rec.is_locked = rec.status_payment in ['done', 'reject'] or rec.status in ['pengajuan3', 'refund', 'reject'] @api.depends('sale_order_ids.name', 'invoice_ids.name') def _compute_order_invoice_names(self): @@ -506,19 +510,19 @@ class RefundSaleOrder(models.Model): if not rec.status or rec.status == 'draft': rec.status = 'pengajuan1' - elif rec.status == 'pengajuan1' and self.env.user.id == 19: + elif rec.status == 'pengajuan1': rec.status = 'pengajuan2' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_sales = now rec.position_sales = 'Sales Manager' - elif rec.status == 'pengajuan2' and self.env.user.id == 688: + elif rec.status == 'pengajuan2': rec.status = 'pengajuan3' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_ar = now rec.position_ar = 'AR' - elif rec.status == 'pengajuan3' and self.env.user.id == 7: + elif rec.status == 'pengajuan3': rec.status = 'refund' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_pimpinan = now @@ -532,7 +536,7 @@ class RefundSaleOrder(models.Model): is_fat = self.env.user.has_group('indoteknik_custom.group_role_fat') allowed_user_ids = [19, 688, 7] for rec in self: - if self.user.id not in allowed_user_ids and not is_fat: + if self.env.uid not in allowed_user_ids and not is_fat: raise UserError("❌ Hanya user yang bersangkutan atau Finance (FAT) yang bisa melakukan penolakan.") if rec.status not in ['refund', 'reject']: rec.status = 'reject' @@ -548,7 +552,7 @@ class RefundSaleOrder(models.Model): is_fat = self.env.user.has_group('indoteknik_custom.group_role_fat') for rec in self: if not is_fat: - raise UserError("Hanya Finance yang dapat mengkonfirmasi refund.") + raise UserError("Hanya Finance yang dapat mengkonfirmasi pembayaran refund.") if rec.status_payment == 'pending': rec.status_payment = 'done' rec.refund_date = fields.Date.context_today(self) diff --git a/indoteknik_custom/views/ir_sequence.xml b/indoteknik_custom/views/ir_sequence.xml index 4915e4c5..94c2cd07 100644 --- a/indoteknik_custom/views/ir_sequence.xml +++ b/indoteknik_custom/views/ir_sequence.xml @@ -220,7 +220,7 @@ - Refund Sale Order + Refund Sales Order refund.sale.order RC/%(year)s/%(month)s/ 4 diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index e35e76b3..27c5feec 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -56,7 +56,7 @@
@@ -163,8 +163,8 @@ - - + + -- cgit v1.2.3 From bbc454fd6e13d12e9674769a555264f2c2343b5b Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Wed, 20 Aug 2025 09:06:33 +0700 Subject: refund system sisa uang muka --- indoteknik_custom/models/refund_sale_order.py | 226 +++++++++++++++++++++----- indoteknik_custom/models/sale_order.py | 80 +++++++-- indoteknik_custom/views/refund_sale_order.xml | 40 ++++- indoteknik_custom/views/sale_order.xml | 4 +- 4 files changed, 292 insertions(+), 58 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 077809e9..2dc72f0f 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -17,13 +17,17 @@ class RefundSaleOrder(models.Model): note_refund = fields.Text(string='Note Refund') sale_order_ids = fields.Many2many('sale.order', string='Sales Order Numbers') uang_masuk = fields.Float(string='Uang Masuk', required=True) - total_invoice = fields.Float(string='Total Invoice') + total_invoice = fields.Float(string='Total Order') ongkir = fields.Float(string='Ongkir', required=True, default=0.0) amount_refund = fields.Float(string='Total Refund', required=True) amount_refund_text = fields.Char(string='Total Refund Text', compute='_compute_refund_text') user_ids = fields.Many2many('res.users', string='Salespersons', compute='_compute_user_ids', domain=[('active', 'in', [True, False])]) create_uid = fields.Many2one('res.users', string='Created By', readonly=True) created_date = fields.Date(string='Tanggal Request Refund', readonly=True) + sale_order_count = fields.Integer( + string="Sale Order Count", + compute="_compute_sale_order_count", + ) status = fields.Selection([ ('draft', 'Draft'), ('pengajuan1', 'Approval Sales Manager'), @@ -55,7 +59,7 @@ class RefundSaleOrder(models.Model): ('uang', 'Refund Lebih Bayar'), ('retur_half', 'Refund Retur Sebagian'), ('retur', 'Refund Retur Full'), - ('lainnya', 'Lainnya') + ('salah_transfer', 'Salah Transfer') ], string='Refund Type', required=True) refund_type_display = fields.Char(string="Refund Type Label", compute="_compute_refund_type_display") @@ -89,7 +93,7 @@ class RefundSaleOrder(models.Model): bukti_refund_type = fields.Selection([ ('pdf', 'PDF'), ('image', 'Image'), - ], string="Attachment Type", default='image') + ], string="Attachment Type") bukti_uang_masuk_image = fields.Binary(string="Upload Bukti Uang Masuk") bukti_transfer_refund_image = fields.Binary(string="Upload Bukti Transfer Refund") bukti_uang_masuk_pdf = fields.Binary(string="Upload Bukti Uang Masuk") @@ -107,22 +111,44 @@ class RefundSaleOrder(models.Model): is_locked = fields.Boolean(string="Locked", compute="_compute_is_locked") sale_order_names_jasper = fields.Char(string='Sales Order List', compute='_compute_order_invoice_names') invoice_names_jasper = fields.Char(string='Invoice List', compute='_compute_order_invoice_names') - - - - @api.depends('refund_type') - def _compute_refund_type_display(self): - for rec in self: - rec.refund_type_display = dict(self.fields_get(allfields=['refund_type'])['refund_type']['selection']).get(rec.refund_type, '') + so_order_line_ids = fields.Many2many( + "sale.order.line", string="SO Order Lines", compute="_compute_so_order_lines", store=False + ) + currency_id = fields.Many2one( + "res.currency", string="Currency", + default=lambda self: self.env.company.currency_id, required=True + ) + + amount_untaxed = fields.Monetary( + string="Untaxed Amount", compute="_compute_amount_from_so", + ) + amount_tax = fields.Monetary( + string="Taxes", compute="_compute_amount_from_so", + ) + amount_total = fields.Monetary( + string="Total", compute="_compute_amount_from_so", + ) + total_margin = fields.Monetary( + string="Total Margin", compute="_compute_amount_from_so", + ) + grand_total = fields.Monetary( + string="Grand Total", compute="_compute_amount_from_so", + ) + delivery_amt = fields.Monetary( + string="Delivery Amount", help="Ongkos kirim yang Dibayarkan Customer", default=0.0, compute="_compute_amount_from_so", + ) + remaining_refundable = fields.Float( + string="Sisa Uang Masuk", + help="Sisa uang masuk yang masih bisa direfund (hanya berlaku untuk 1 SO)", + ) - @api.model def create(self, vals): allowed_user_ids = [23, 19, 688, 7] if not ( self.env.user.has_group('indoteknik_custom.group_role_sales') or self.env.user.has_group('indoteknik_custom.group_role_fat') or - self.env.user.id not in allowed_user_ids + self.env.user.id in allowed_user_ids ): raise UserError("❌ Hanya Sales dan Finance yang boleh membuat refund.") @@ -158,9 +184,20 @@ class RefundSaleOrder(models.Model): if refund_type in ['barang_kosong', 'barang_kosong_sebagian'] and so_ids: sale_orders = self.env['sale.order'].browse(so_ids) - zero_delivery_lines = sale_orders.mapped('order_line').filtered(lambda l: l.qty_delivered == 0) - if not zero_delivery_lines: - raise UserError("❌ Tidak ada barang yang Tidak Terikirim di Sales Order yang dipilih.") + + if refund_type == 'barang_kosong': + zero_delivery_lines = sale_orders.mapped('order_line').filtered( + lambda l: l.qty_delivered == 0 and l.product_uom_qty > 0 + ) + if not zero_delivery_lines: + raise UserError("❌ Tidak ada barang kosong di SO yang terpilih.") + + elif refund_type == 'barang_kosong_sebagian': + partial_delivery_lines = sale_orders.mapped('order_line').filtered( + lambda l: l.qty_delivered > 0 and l.product_uom_qty > l.qty_delivered + ) + if not partial_delivery_lines: + raise UserError("❌ Tidak ada barang yang tidak Terkirim/Kosong di SO yang dipilih.") if not so_ids and refund_type != 'lainnya': @@ -180,22 +217,40 @@ class RefundSaleOrder(models.Model): if refund_type == 'retur_half' and not invoice_ids: raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk Retur Sebagian.") - total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) if invoice_ids else 0.0 - ongkir = vals.get('ongkir', 0.0) - vals['total_invoice'] = total_invoice - pengurangan = total_invoice + ongkir - if refund_type == 'barang_kosong_sebagian' and so_ids: sale_orders = self.env['sale.order'].browse(so_ids) vals['uang_masuk'] = sum(sale_orders.mapped('amount_total')) - - uang_masuk = vals.get('uang_masuk', 0.0) + moves = self.env['account.move'].search([ + ('sale_id', 'in', so_ids), + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ]) + total_uang_muka = sum(moves.mapped('amount_total_signed')) - if uang_masuk > pengurangan: - vals['amount_refund'] = uang_masuk - pengurangan - else: - raise UserError("Uang masuk harus lebih besar dari total invoice + ongkir untuk melakukan refund") + uang_masuk = total_uang_muka if moves else sum(self.env['sale.order'].browse(so_ids).mapped('gross_amount')) + vals['uang_masuk'] = uang_masuk + ongkir = vals.get('ongkir', 0.0) + 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) + if amount_refund <= 0.00: + raise ValidationError('Total Refund harus lebih dari 0 jika ingin mengajukan refund') + + if so_ids and len(so_ids) > 1: + existing_refund = self.search([('sale_order_ids', 'in', so_ids)], limit=1) + if existing_refund: + raise UserError("❌ Refund multi SO hanya bisa 1 kali.") + vals['remaining_refundable'] = 0.0 + elif so_ids and len(so_ids) == 1: + so = self.env['sale.order'].browse(so_ids[0]) + existing_refunds = self.search([('sale_order_ids', 'in', so_ids)]) + total_refunded = sum(existing_refunds.mapped('amount_refund')) + amount_refund + remaining = uang_masuk - total_refunded + if remaining < 0: + raise ValidationError("❌ Tidak ada sisa transaksi untuk di-refund di SO ini. Semua dana sudah dikembalikan.") + vals['remaining_refundable'] = remaining return super().create(vals) @@ -285,20 +340,41 @@ class RefundSaleOrder(models.Model): if refund_type == 'retur_half' and not invoice_ids: raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk retur sebagian.") - if any(field in vals for field in ['uang_masuk', 'invoice_ids', 'ongkir', 'sale_order_ids']): + 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 = vals.get('uang_masuk', rec.uang_masuk) - ongkir = vals.get('ongkir', rec.ongkir) + uang_masuk = rec.uang_masuk + amount_refund = vals.get('amount_refund', rec.amount_refund) + + if amount_refund <= 0: + raise ValidationError("Total Refund harus lebih dari 0.") + + existing_refunds = self.search([ + ('sale_order_ids', 'in', so_ids), + ('id', '!=', rec.id) + ]) + total_refunded = sum(existing_refunds.mapped('amount_refund')) + amount_refund + remaining = uang_masuk - total_refunded - if uang_masuk <= (total_invoice + ongkir): - raise UserError("Uang masuk harus lebih besar dari total invoice + ongkir") - vals['amount_refund'] = uang_masuk - (total_invoice + ongkir) + if remaining < 0: + raise ValidationError("❌ Dana uang masuk telah sepenuhnya di refund tidak bisa Mengubah Nominal Refund") - if vals.get('status') == 'refund' and not vals.get('refund_date'): - vals['refund_date'] = fields.Date.context_today(self) + vals['remaining_refundable'] = remaining return super().write(vals) + + @api.onchange('ongkir', 'amount_refund') + def _onchange_refund_fields(self): + for rec in self: + uang_masuk = rec.uang_masuk or 0.0 + ongkir = rec.ongkir or 0.0 + refund_input = rec.amount_refund or 0.0 + + total_refund_with_ongkir = refund_input + ongkir + if total_refund_with_ongkir > uang_masuk: + raise UserError("❌ Refund + Ongkir tidak boleh melebihi Uang Masuk.") + remaining = uang_masuk - refund_input + rec.remaining_refundable = remaining @api.depends('status_payment', 'status') def _compute_is_locked(self): @@ -362,6 +438,37 @@ class RefundSaleOrder(models.Model): if self.sale_order_ids: self.partner_id = self.sale_order_ids[0].partner_id + @api.constrains('sale_order_ids') + def _check_sale_orders_payment(self): + """ Validasi SO harus punya uang masuk (Journal Uang Muka / Midtrans) """ + for rec in self: + invalid_orders = [] + total_uang_masuk = 0.0 + + for so in rec.sale_order_ids: + # cari journal uang muka + moves = self.env['account.move'].search([ + ('sale_id', '=', so.id), + ('journal_id', '=', 11), # Journal Uang Muka + ('state', '=', 'posted'), + ]) + + if not moves and so.payment_status != 'settlement': + invalid_orders.append(so.name) + + if moves: + total_uang_muka = sum(moves.mapped('amount_total_signed')) or 0.0 + total_uang_masuk += total_uang_muka + else: + # fallback Midtrans gross_amount + total_uang_masuk += so.gross_amount or 0.0 + + if invalid_orders: + raise ValidationError( + f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} " + "karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Midtrans).\n" + "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid." + ) @api.onchange('refund_type') def _onchange_refund_type(self): @@ -374,14 +481,12 @@ class RefundSaleOrder(models.Model): line_vals.append((0, 0, { 'product_id': line.product_id.id, 'quantity': line.product_uom_qty, + 'product_from': line.order_id.name, 'reason': '', })) self.line_ids = line_vals - if self.refund_type == 'barang_kosong_sebagian' and self.sale_order_ids: - self.uang_masuk = sum(self.sale_order_ids.mapped('amount_total')) + sum(self.sale_order_ids.mapped('delivery_amt')) - elif self.refund_type in ['retur', 'retur_half'] and self.sale_order_ids: line_vals = [] StockPicking = self.env['stock.picking'] @@ -476,6 +581,7 @@ class RefundSaleOrder(models.Model): line_vals.append((0, 0, { 'product_id': line.product_id.id, 'quantity': line.product_uom_qty, + 'product_from': line.order_id.name, 'reason': '', })) res['line_ids'] = line_vals @@ -671,7 +777,52 @@ class RefundSaleOrder(models.Model): } + @api.depends( + "sale_order_ids", + "sale_order_ids.order_line.price_subtotal", + "sale_order_ids.order_line.price_tax", + "sale_order_ids.order_line.price_total", + "sale_order_ids.order_line.purchase_price", + "sale_order_ids.order_line.product_uom_qty", + "sale_order_ids.delivery_amt", + "sale_order_ids.shipping_cost_covered", + ) + def _compute_amount_from_so(self): + for rec in self: + untaxed = tax = total_margin = delivery = 0.0 + for so in rec.sale_order_ids: + if so.shipping_cost_covered == 'customer': + delivery += so.delivery_amt or 0.0 + for line in so.order_line: + untaxed += line.price_subtotal + tax += line.price_tax + cost = line.purchase_price * line.product_uom_qty + margin = line.price_subtotal - cost + total_margin += margin + rec.amount_untaxed = untaxed + rec.amount_tax = tax + rec.amount_total = untaxed + tax + rec.total_margin = total_margin + rec.delivery_amt = delivery + rec.grand_total = rec.amount_total + rec.delivery_amt + + + @api.depends("sale_order_ids", "sale_order_ids.order_line") + def _compute_so_order_lines(self): + for rec in self: + rec.so_order_line_ids = rec.sale_order_ids.mapped("order_line") + + + + @api.depends('refund_type') + def _compute_refund_type_display(self): + for rec in self: + rec.refund_type_display = dict(self.fields_get(allfields=['refund_type'])['refund_type']['selection']).get(rec.refund_type, '') + + def _compute_sale_order_count(self): + for rec in self: + rec.sale_order_count = len(rec.sale_order_ids) class RefundSaleOrderLine(models.Model): _name = 'refund.sale.order.line' @@ -682,3 +833,4 @@ class RefundSaleOrderLine(models.Model): product_id = fields.Many2one('product.product', string='Product') quantity = fields.Float(string='Qty') reason = fields.Char(string='Reason') + product_from = fields.Char(string='Product Reference') diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index aa534d0c..2acee890 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -358,7 +358,6 @@ class SaleOrder(models.Model): help="Tanggal pertama kali barang berhasil di-reservasi pada DO (BU/PICK/) yang berstatus Siap Dikirim." ) refund_ids = fields.Many2many('refund.sale.order', compute='_compute_refund_ids', string='Refunds') - has_refund = fields.Boolean(string='Has Refund', compute='_compute_has_refund') refund_count = fields.Integer(string='Refund Count', compute='_compute_refund_count') advance_payment_move_id = fields.Many2one( 'account.move', @@ -3197,9 +3196,35 @@ class SaleOrder(models.Model): def button_refund(self): self.ensure_one() + moves = self.env['account.move'].search([ + ('sale_id', '=', self.id), + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ]) + + # Default 0 + total_uang_muka = 0.0 + has_moves = bool(moves) + has_settlement = self.payment_status == 'settlement' + + if has_moves and has_settlement: + total_uang_muka = sum(moves.mapped('amount_total_signed')) + self.gross_amount + elif has_moves: + total_uang_muka = sum(moves.mapped('amount_total_signed')) + elif has_settlement: + total_uang_muka = self.gross_amount + else: + raise UserError( + "Tidak bisa melakukan refund karena SO tidak memiliki Record Uang Masuk " + "(Journal Uang Muka/Midtrans Payment)." + ) invoice_ids = self.invoice_ids.filtered(lambda inv: inv.state != 'cancel') - total_so = sum(self.mapped('amount_total')) + total_refunded = sum(self.refund_ids.mapped('amount_refund')) or 0.0 + sisa_uang_muka = total_uang_muka - total_refunded + + if sisa_uang_muka <= 0: + raise UserError("❌ Tidak ada sisa transaksi untuk di-refund. Semua dana sudah dikembalikan.") return { 'name': 'Refund Sale Order', @@ -3210,9 +3235,9 @@ class SaleOrder(models.Model): 'context': { 'default_sale_order_ids': [(6, 0, [self.id])], 'default_invoice_ids': [(6, 0, invoice_ids.ids)], - 'default_uang_masuk': total_so, + 'default_uang_masuk': sisa_uang_muka, 'default_ongkir': self.delivery_amt or 0.0, - 'default_bank': '', # bisa isi default bank kalau mau + 'default_bank': '', 'default_account_name': '', 'default_account_no': '', 'default_refund_type': '', @@ -3231,15 +3256,43 @@ class SaleOrder(models.Model): if len(invoice_status_set) > 1: raise UserError("Tidak dapat membuat refund untuk SO dengan status invoice berbeda. Harus memiliki status invoice yang sama.") - already_refunded = self.filtered(lambda so: so.has_refund) - if already_refunded: - so_names = ', '.join(already_refunded.mapped('name')) - raise UserError(f"❌ Tidak bisa refund ulang. {so_names} sudah melakukan refund.") + refunded_orders = self.filtered(lambda so: self.env['refund.sale.order'].search([('sale_order_ids', 'in', so.id)], limit=1)) + if refunded_orders: + raise ValidationError( + f"SO {', '.join(refunded_orders.mapped('name'))} sudah pernah di-refund dan tidak bisa ikut dalam refund Multi SO." + ) + + total_uang_masuk = 0.0 + invalid_orders=[] + for order in self: + moves = self.env['account.move'].search([ + ('sale_id', '=', order.id), + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ]) + + total_uang_muka = 0.0 + + if moves and order.payment_status == 'settlement': + total_uang_muka = order.gross_amount + sum(moves.mapped('amount_total_signed')) or 0.0 + elif moves: + total_uang_muka = sum(moves.mapped('amount_total_signed')) or 0.0 + elif order.payment_status == 'settlement': + total_uang_muka = order.gross_amount + else: + invalid_orders.append(order.name) + + total_uang_masuk += total_uang_muka + + if invalid_orders: + raise ValidationError( + f"Tidak dapat membuat refund untuk SO {', '.join(invalid_orders)} karena tidak memiliki Record Uang Masuk (Journal Uang Muka/Midtrans).\n" + "Pastikan semua SO yang dipilih sudah memiliki Record pembayaran yang valid." + ) + invoice_ids = self.mapped('invoice_ids').filtered(lambda inv: inv.state != 'cancel') delivery_total = sum(self.mapped('delivery_amt')) - total_invoice = sum(invoice_ids.mapped('amount_total_signed')) - total_so = sum(self.mapped('amount_total')) return { 'type': 'ir.actions.act_window', @@ -3250,7 +3303,7 @@ class SaleOrder(models.Model): 'context': { 'default_sale_order_ids': [(6, 0, self.ids)], 'default_invoice_ids': [(6, 0, invoice_ids.ids)], - 'default_uang_masuk': total_so, + 'default_uang_masuk': total_uang_masuk, 'default_ongkir': delivery_total, 'default_bank': '', 'default_account_name': '', @@ -3259,11 +3312,6 @@ class SaleOrder(models.Model): } } - @api.depends('refund_ids') - def _compute_has_refund(self): - for so in self: - so.has_refund = bool(so.refund_ids) - def action_view_related_refunds(self): self.ensure_one() return { diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index 27c5feec..dd47c2ab 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -14,6 +14,7 @@ + - + + + @@ -133,7 +136,8 @@ - + + @@ -168,6 +172,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 1d51fd69..8f8e4288 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -39,8 +39,7 @@ + + - + -- cgit v1.2.3 From 101948d6029b06a69759b8f246f1744312f035c0 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Fri, 29 Aug 2025 10:52:19 +0700 Subject: (andri) add is locked CBD jika ada customer yang sudah jatuh tempo --- indoteknik_custom/models/account_move.py | 28 +++++++++++++++++++++++ indoteknik_custom/models/approval_payment_term.py | 3 ++- indoteknik_custom/models/res_partner.py | 15 ++++++++---- indoteknik_custom/models/sale_order.py | 9 ++++++++ indoteknik_custom/views/res_partner.xml | 1 + indoteknik_custom/views/sale_order.xml | 9 ++++++++ 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c44cad78..55e640e4 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -105,6 +105,34 @@ class AccountMove(models.Model): tracking=True ) + def _check_and_lock_cbd(self): + cbd_term = self.env['account.payment.term'].browse(26) + today = date.today() + + # Cari semua invoice overdue + overdue_invoices = self.search([ + ('move_type', '=', 'out_invoice'), + ('state', '=', 'posted'), + ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), + ('invoice_date_due', '!=', False), + ('invoice_date_due', '<=', today - timedelta(days=30)), + ], limit=3) + + _logger.info(f"Found {len(overdue_invoices)} overdue invoices for CBD lock check.") + _logger.info(f"Overdue Invoices: {overdue_invoices.mapped('name')}") + + # Ambil partner unik dari invoice + partners_to_lock = overdue_invoices.mapped('partner_id').filtered(lambda p: not p.is_cbd_locked) + _logger.info(f"Partners to lock: {partners_to_lock.mapped('name')}") + + # Lock hanya partner yang belum locked + if partners_to_lock: + partners_to_lock.write({ + 'is_cbd_locked': True, + 'property_payment_term_id': cbd_term.id, + }) + + def compute_partial_payment(self): for move in self: if move.amount_total_signed > 0 and move.amount_residual_signed > 0 and move.payment_state == 'partial': diff --git a/indoteknik_custom/models/approval_payment_term.py b/indoteknik_custom/models/approval_payment_term.py index 8618856a..08d91738 100644 --- a/indoteknik_custom/models/approval_payment_term.py +++ b/indoteknik_custom/models/approval_payment_term.py @@ -171,7 +171,8 @@ class ApprovalPaymentTerm(models.Model): 'blocking_stage': self.blocking_stage, 'warning_stage': self.warning_stage, 'active_limit': self.active_limit, - 'property_payment_term_id': self.property_payment_term_id.id + 'property_payment_term_id': self.property_payment_term_id.id, + 'is_locked_cbd': False, }) self.approve_date = datetime.utcnow() self.state = 'approved' diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 148a3fd0..017be730 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -1,6 +1,6 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError -from datetime import datetime +from datetime import datetime, timedelta from odoo.http import request import re import requests @@ -181,10 +181,15 @@ class ResPartner(models.Model): payment_difficulty = fields.Selection([('bermasalah', 'Bermasalah'),('sulit', 'Sulit'),('agak_sulit', 'Agak Sulit'),('normal', 'Normal')], string='Payment Difficulty', tracking=3) payment_history_url = fields.Text(string='Payment History URL') - # no compute - # payment_diff = fields.Selection([('bermasalah', 'Bermasalah'),('sulit', 'Sulit'),('agak_sulit', 'Agak Sulit'),('normal', 'Normal')], string='Payment Difficulty', tracking=3) - - # tidak terpakai + is_cbd_locked = fields.Boolean("Locked to CBD?", default=False, tracking=True, help="Jika dicentang, maka partner ini terkunci pada payment term CBD karena memiliki invoice yang sudah jatuh tempo lebih dari 30 hari.") + + # centang manual is_cbd_locked jika payment term diubah ke CBD + @api.onchange('is_cbd_locked') + def _onchange_is_cbd_locked(self): + if self.is_cbd_locked: + cbd_term = self.env['account.payment.term'].browse(26) + if cbd_term: + self.property_payment_term_id = cbd_term.id @api.model def _default_payment_term(self): diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index ffb53dce..992c1a5d 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -394,6 +394,15 @@ class SaleOrder(models.Model): ('paid', 'Full Paid'), ('no_invoice', 'No Invoice'), ], string="Payment Status Invoice", compute="_compute_payment_state_custom", store=False) + partner_is_cbd_locked = fields.Boolean( + string="Partner Locked CBD", + compute="_compute_partner_is_cbd_locked" + ) + + @api.depends('partner_id.is_cbd_locked') + def _compute_partner_is_cbd_locked(self): + for order in self: + order.partner_is_cbd_locked = order.partner_id.is_cbd_locked @api.depends('invoice_ids.payment_state', 'invoice_ids.amount_total', 'invoice_ids.amount_residual') def _compute_payment_state_custom(self): diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index ca1a36de..7541df35 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -21,6 +21,7 @@ + diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index a1a5e0cd..29d1a980 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -42,6 +42,15 @@ class="btn-primary" attrs="{'invisible': ['|', ('state', 'not in', ['sale', 'done']), ('has_refund', '=', True)]}" /> --> + + + +
+ +
@@ -101,12 +106,24 @@ attrs="{'invisible': [('journal_refund_move_id', '=', False)]}"> - + +
- - - - - + + + + + + +
- - + + + @@ -157,9 +179,17 @@ - + + + + + + + + + @@ -176,6 +206,7 @@ +
@@ -230,11 +261,34 @@ + + + + + + + + + + + + + + + + +
+
-- cgit v1.2.3 From fd2d67cacb3015e346b9656b7329606066c2f95a Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 29 Aug 2025 15:01:45 +0700 Subject: fix return selain SO PO --- indoteknik_custom/models/stock_picking_return.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/stock_picking_return.py b/indoteknik_custom/models/stock_picking_return.py index 1fc8d088..88acf83c 100644 --- a/indoteknik_custom/models/stock_picking_return.py +++ b/indoteknik_custom/models/stock_picking_return.py @@ -110,7 +110,7 @@ class ReturnPicking(models.TransientModel): if mapping_koli_vals: context['default_mapping_koli_ids'] = mapping_koli_vals - if picking.purchase_id or 'PO' in picking.origin: + if picking.purchase_id or 'PO' in (picking.origin or ''): _logger.info("Redirect ke Tukar Guling PO via purchase_id / origin") return { 'name': _('Tukar Guling PO'), @@ -120,7 +120,7 @@ class ReturnPicking(models.TransientModel): 'target': 'current', 'context': context, } - else: + if picking.sale_id or 'SO' in (picking.origin or ''): _logger.info("This picking is NOT from a PO, fallback to SO.") return { 'name': _('Tukar Guling SO'), @@ -130,6 +130,9 @@ class ReturnPicking(models.TransientModel): 'target': 'current', 'context': context, } + else: + _logger.info("Bukan SO/PO → retur standar (create_returns)") + return super(ReturnPicking, self).create_returns() class ReturnPickingLine(models.TransientModel): -- cgit v1.2.3 From 0298605049e29ef436a5e6984b743f89fed712b3 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 30 Aug 2025 09:23:35 +0700 Subject: last logic unlink --- indoteknik_custom/models/refund_sale_order.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 086c7a81..51907083 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -660,10 +660,10 @@ class RefundSaleOrder(models.Model): record.amount_refund_text = '' def unlink(self): - not_draft = self.filtered(lambda r: r.status != 'draft') - if not_draft: - names = ', '.join(not_draft.mapped('name')) - raise UserError(f"Refund hanya bisa dihapus jika statusnya masih draft.\nTidak bisa hapus: {names}") + incantdelete = self.filtered(lambda r: r.status in ['refund', 'reject']) + if incantdelete: + names = ', '.join(incantdelete.mapped('name')) + raise UserError(f"Refund tidak dapat di hapus jika sudah Confirm/Cancel.\nTidak bisa hapus: {names}") return super().unlink() @api.depends('invoice_ids') -- cgit v1.2.3 From 19e63a5715369a740f209c49115a90967a6aa7d6 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Sat, 30 Aug 2025 09:58:22 +0700 Subject: fix validation approval --- indoteknik_custom/models/refund_sale_order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 51907083..6d0b5741 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -751,19 +751,19 @@ class RefundSaleOrder(models.Model): if not rec.status or rec.status == 'draft': rec.status = 'pengajuan1' - elif rec.status == 'pengajuan1': + elif rec.status == 'pengajuan1' and self.env.user.id == 19: rec.status = 'pengajuan2' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_sales = now rec.position_sales = 'Sales Manager' - elif rec.status == 'pengajuan2': + elif rec.status == 'pengajuan2' and self.env.user.id == 688: rec.status = 'pengajuan3' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_ar = now rec.position_ar = 'AR' - elif rec.status == 'pengajuan3': + elif rec.status == 'pengajuan3' and self.env.user.id == 7: rec.status = 'refund' rec.approved_by = f"{rec.approved_by}, {user_name}" if rec.approved_by else user_name rec.date_approved_pimpinan = now -- cgit v1.2.3 From 7186c4657cb85d2175222b4bebc55456e6970a3a Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 30 Aug 2025 10:09:06 +0700 Subject: unlink val vcm ccm --- indoteknik_custom/models/tukar_guling.py | 4 ++-- indoteknik_custom/models/tukar_guling_po.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index 699ee670..e9cbf246 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -435,9 +435,9 @@ class TukarGuling(models.Model): # if self.state == 'done': # raise UserError ("Tidak Boleh delete ketika sudahh done") for record in self: - if record.state == 'approved' or record.state == 'done': + if record.state in [ 'approved', 'done', 'approval_logistic', 'approval_finance', 'approval_sales']: raise UserError( - "Tidak bisa hapus pengajuan jika sudah Approved, set ke draft terlebih dahulu jika ingin menghapus") + "Tidak bisa hapus pengajuan jika sudah Proses Approval, set ke draft terlebih dahulu atau cancel jika ingin menghapus") ongoing_bu = self.picking_ids.filtered(lambda p: p.state != 'approved') for picking in ongoing_bu: picking.action_cancel() diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index 94771f37..f2f37606 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -381,8 +381,8 @@ class TukarGulingPO(models.Model): def unlink(self): for record in self: - if record.state == 'done' or record.state == 'approved': - raise UserError("Tidak bisa hapus pengajuan jika sudah done, set ke draft terlebih dahulu") + if record.state in [ 'approved', 'done', 'approval_logistic', 'approval_finance', 'approval_purchase']: + raise UserError("Tidak bisa hapus pengajuan jika sudah proses approval atau done, set ke draft atau cancel terlebih dahulu") ongoing_bu = self.po_picking_ids.filtered(lambda p: p.state != 'done') for picking in ongoing_bu: picking.action_cancel() -- cgit v1.2.3 From d91498b1aae363a3c51023a0fc8bc8086a294838 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 1 Sep 2025 09:40:59 +0700 Subject: --- indoteknik_custom/security/ir.model.access.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 866a7140..3a320510 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -194,4 +194,5 @@ access_tukar_guling_line_po_all_users,tukar.guling.line.po.all.users,model_tukar access_tukar_guling_mapping_koli_all_users,tukar.guling.mapping.koli.all.users,model_tukar_guling_mapping_koli,base.group_user,1,1,1,1 access_purchase_order_update_date_wizard,access.purchase.order.update.date.wizard,model_purchase_order_update_date_wizard,base.group_user,1,1,1,1 access_sync_promise_date_wizard,access.sync.promise.date.wizard,model_sync_promise_date_wizard,base.group_user,1,1,1,1 -access_sync_promise_date_wizard_line,access.sync.promise.date.wizard.line,model_sync_promise_date_wizard_line,base.group_user,1,1,1,1 \ No newline at end of file +access_sync_promise_date_wizard_line,access.sync.promise.date.wizard.line,model_sync_promise_date_wizard_line,base.group_user,1,1,1,1 +access_change_date_planned_wizard,access.change.date.planned.wizard,model_change_date_planned_wizard,,1,1,1,1 \ No newline at end of file -- cgit v1.2.3 From d7a5e47f741211e9750c21ac148331d6e29bdc16 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Mon, 1 Sep 2025 10:00:32 +0700 Subject: (andri) add sum grand total tree dunning run --- indoteknik_custom/views/dunning_run.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 210f7917..f624c42e 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -13,7 +13,7 @@ - + -- cgit v1.2.3 From 77539c2e9ee720c7e731d1b5138041263394a978 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 2 Sep 2025 11:12:22 +0700 Subject: fix refund ongkir --- indoteknik_custom/models/refund_sale_order.py | 29 ++++++++------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 6d0b5741..737419e7 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -392,6 +392,7 @@ class RefundSaleOrder(models.Model): total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) vals['total_invoice'] = total_invoice uang_masuk = rec.uang_masuk + amount_refund = vals.get('amount_refund', rec.amount_refund) if amount_refund <= 0: @@ -401,36 +402,22 @@ class RefundSaleOrder(models.Model): ('sale_order_ids', 'in', so_ids), ('id', '!=', rec.id) ]) - total_refunded = sum(existing_refunds.mapped('amount_refund')) + amount_refund - remaining = uang_masuk - total_refunded + total_refunded = sum(existing_refunds.mapped('amount_refund')) + if existing_refunds: + remaining = uang_masuk - total_refunded + else: + remaining = uang_masuk - amount_refund - if remaining < 0: - raise ValidationError("❌ Dana uang masuk telah sepenuhnya di refund tidak bisa Mengubah Nominal Refund") vals['remaining_refundable'] = remaining return super().write(vals) - @api.onchange('ongkir', 'amount_refund') + @api.onchange('amount_refund') def _onchange_refund_fields(self): for rec in self: refund_input = rec.amount_refund or 0.0 - - # ambil refund terakhir untuk SO - existing_refund = self.env['refund.sale.order'].search([ - ('sale_order_ids', 'in', rec.sale_order_ids.ids) - ], order='id desc', limit=1) - - if existing_refund: - sisa_uang_masuk = existing_refund.remaining_refundable - else: - sisa_uang_masuk = rec.uang_masuk or 0.0 - - # update field uang_masuk supaya form menampilkan sisa aktual - rec.uang_masuk = sisa_uang_masuk - - # hitung remaining setelah input refund - rec.remaining_refundable = sisa_uang_masuk - refund_input + rec.remaining_refundable = (rec.uang_masuk or 0.0) - refund_input @api.depends('status_payment', 'status') def _compute_is_locked(self): -- cgit v1.2.3 From ed459eb048e8e14075134ead0cb80d5da864af53 Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 2 Sep 2025 11:39:22 +0700 Subject: (andri) comment method --- indoteknik_custom/models/account_move.py | 52 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index 55e640e4..7884b1d5 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -105,32 +105,32 @@ class AccountMove(models.Model): tracking=True ) - def _check_and_lock_cbd(self): - cbd_term = self.env['account.payment.term'].browse(26) - today = date.today() - - # Cari semua invoice overdue - overdue_invoices = self.search([ - ('move_type', '=', 'out_invoice'), - ('state', '=', 'posted'), - ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), - ('invoice_date_due', '!=', False), - ('invoice_date_due', '<=', today - timedelta(days=30)), - ], limit=3) - - _logger.info(f"Found {len(overdue_invoices)} overdue invoices for CBD lock check.") - _logger.info(f"Overdue Invoices: {overdue_invoices.mapped('name')}") - - # Ambil partner unik dari invoice - partners_to_lock = overdue_invoices.mapped('partner_id').filtered(lambda p: not p.is_cbd_locked) - _logger.info(f"Partners to lock: {partners_to_lock.mapped('name')}") - - # Lock hanya partner yang belum locked - if partners_to_lock: - partners_to_lock.write({ - 'is_cbd_locked': True, - 'property_payment_term_id': cbd_term.id, - }) + # def _check_and_lock_cbd(self): + # cbd_term = self.env['account.payment.term'].browse(26) + # today = date.today() + + # # Cari semua invoice overdue + # overdue_invoices = self.search([ + # ('move_type', '=', 'out_invoice'), + # ('state', '=', 'posted'), + # ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), + # ('invoice_date_due', '!=', False), + # ('invoice_date_due', '<=', today - timedelta(days=30)), + # ], limit=3) + + # _logger.info(f"Found {len(overdue_invoices)} overdue invoices for CBD lock check.") + # _logger.info(f"Overdue Invoices: {overdue_invoices.mapped('name')}") + + # # Ambil partner unik dari invoice + # partners_to_lock = overdue_invoices.mapped('partner_id').filtered(lambda p: not p.is_cbd_locked) + # _logger.info(f"Partners to lock: {partners_to_lock.mapped('name')}") + + # # Lock hanya partner yang belum locked + # if partners_to_lock: + # partners_to_lock.write({ + # 'is_cbd_locked': True, + # 'property_payment_term_id': cbd_term.id, + # }) def compute_partial_payment(self): -- cgit v1.2.3 From 70dfadc9aa8274e8f9aafa4ec594af0b5a37343b Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Tue, 2 Sep 2025 12:00:26 +0700 Subject: (andri) add tracking payment terms dan fix notif ketika membuat SO --- indoteknik_custom/models/res_partner.py | 14 +++++++------- indoteknik_custom/views/sale_order.xml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 017be730..80fe643b 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -184,12 +184,12 @@ class ResPartner(models.Model): is_cbd_locked = fields.Boolean("Locked to CBD?", default=False, tracking=True, help="Jika dicentang, maka partner ini terkunci pada payment term CBD karena memiliki invoice yang sudah jatuh tempo lebih dari 30 hari.") # centang manual is_cbd_locked jika payment term diubah ke CBD - @api.onchange('is_cbd_locked') - def _onchange_is_cbd_locked(self): - if self.is_cbd_locked: - cbd_term = self.env['account.payment.term'].browse(26) - if cbd_term: - self.property_payment_term_id = cbd_term.id + # @api.onchange('is_cbd_locked') + # def _onchange_is_cbd_locked(self): + # if self.is_cbd_locked: + # cbd_term = self.env['account.payment.term'].browse(26) + # if cbd_term: + # self.property_payment_term_id = cbd_term.id @api.model def _default_payment_term(self): @@ -198,7 +198,7 @@ class ResPartner(models.Model): property_payment_term_id = fields.Many2one( 'account.payment.term', string='Payment Terms', - default=_default_payment_term + default=_default_payment_term, tracking=3 ) @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 29d1a980..236a8b14 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -48,7 +48,7 @@ role="alert" style="height: 40px; margin-bottom:0px;" attrs="{'invisible':[('partner_is_cbd_locked','=',False)]}"> - Warning! Payment Terms Customer terkunci menjadi Cash Before Delivery (C.B.D.) karena ada invoice telah jatuh tempo 30 hari. Silakan ajukan Approval Payment Term untuk membuka kunci. + Warning! Payment Terms Customer terkunci menjadi Cash Before Delivery (C.B.D.) karena ada invoice telah jatuh tempo 30 hari. Silakan ajukan Approval Payment Term untuk membuka kunci.
-- cgit v1.2.3 From 71f13fcc278b01133d07d56103bbd45afd967d48 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 2 Sep 2025 13:43:43 +0700 Subject: fix finish Checkout --- indoteknik_api/controllers/api_v1/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 374b49a2..65894d8a 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -87,8 +87,8 @@ class SaleOrder(controller.Controller): 'amount_tax': sale.amount_tax, 'amount_total': sale.amount_total, 'expected_ready_to_ship': f"{sale.expected_ready_to_ship.day} {INDONESIAN_MONTHS[sale.expected_ready_to_ship.month]} {sale.expected_ready_to_ship.year}", - 'eta_date_start': f"{sale.eta_date_start.day} {INDONESIAN_MONTHS[sale.eta_date_start.month]} {sale.eta_date_start.year}", - 'eta_date_end': f"{sale.eta_date.day} {INDONESIAN_MONTHS[sale.eta_date.month]} {sale.eta_date.year}", + # 'eta_date_start': f"{sale.eta_date_start.day} {INDONESIAN_MONTHS[sale.eta_date_start.month]} {sale.eta_date_start.year}", + # 'eta_date_end': f"{sale.eta_date.day} {INDONESIAN_MONTHS[sale.eta_date.month]} {sale.eta_date.year}", 'product_name': product_name, 'product_not_in_id': product_not_in_id, 'details': [request.env['sale.order.line'].api_single_response(x, context='with_detail') for x in sale.order_line] -- cgit v1.2.3 From ddaedc0eeaf53b47786a7747664fc99ae4dc1a7a Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Tue, 2 Sep 2025 14:46:57 +0700 Subject: fix refund validasi --- indoteknik_custom/models/refund_sale_order.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 737419e7..731d8e41 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -408,6 +408,8 @@ class RefundSaleOrder(models.Model): else: remaining = uang_masuk - amount_refund + if remaining < 0: + raise ValidationError("Semua dana sudah dikembalikan, tidak bisa mengajukan refund") vals['remaining_refundable'] = remaining -- cgit v1.2.3 From 461020919518ac0bde4024de482303734fd314dc Mon Sep 17 00:00:00 2001 From: Miqdad Date: Tue, 2 Sep 2025 14:51:29 +0700 Subject: Fix cancel invoice ccm --- indoteknik_custom/models/tukar_guling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/tukar_guling.py b/indoteknik_custom/models/tukar_guling.py index d2e00781..6e839bf0 100644 --- a/indoteknik_custom/models/tukar_guling.py +++ b/indoteknik_custom/models/tukar_guling.py @@ -134,7 +134,7 @@ class TukarGuling(models.Model): if not self.val_inv_opt and self.is_has_invoice == True: raise UserError("Kalau sudah ada invoice Return Invoice Option harus diisi!") for rec in self: - if rec.val_inv_opt == 'cancel_invoice' and self.is_has_invoice == True: + if rec.val_inv_opt == 'cancel_invoice' and self.is_has_invoice == True and rec.invoice_id.state != 'cancel': raise UserError("Tidak bisa mengubah Return karena sudah ada invoice dan belum di cancel.") elif rec.val_inv_opt == 'tanpa_cancel' and self.is_has_invoice == True: continue -- cgit v1.2.3 From f6537c3987112c351a2a099475b1e32a9e8de76e Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 4 Sep 2025 09:39:08 +0700 Subject: Fix singleton mathces SO --- indoteknik_custom/models/purchase_order_sales_match.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order_sales_match.py b/indoteknik_custom/models/purchase_order_sales_match.py index b18864f3..084b93f7 100644 --- a/indoteknik_custom/models/purchase_order_sales_match.py +++ b/indoteknik_custom/models/purchase_order_sales_match.py @@ -39,7 +39,7 @@ class PurchaseOrderSalesMatch(models.Model): ('sale_line_id', '=', rec.sale_line_id.id), ]) if stock_move: - rec.bu_pick = stock_move.picking_id.id + rec.bu_pick = stock_move[0].picking_id.id else: rec.bu_pick = None -- cgit v1.2.3 From 18df26a9a413261a63cf0531078b51f92f0594fc Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 4 Sep 2025 09:41:21 +0700 Subject: fix finance note open lock --- indoteknik_custom/views/refund_sale_order.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index ae0861e2..20a07aa3 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -214,12 +214,12 @@ - + - - - + + + -- cgit v1.2.3 From 14d3ad7bbb8a6bd9c1272685aed4b3712ab1f33d Mon Sep 17 00:00:00 2001 From: "Indoteknik ." Date: Thu, 4 Sep 2025 11:14:27 +0700 Subject: (andri) fix reminder --- indoteknik_custom/models/account_move.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py index c44cad78..c93cfb76 100644 --- a/indoteknik_custom/models/account_move.py +++ b/indoteknik_custom/models/account_move.py @@ -179,9 +179,8 @@ class AccountMove(models.Model): ('state', '=', 'posted'), ('payment_state', 'not in', ['paid', 'in_payment', 'reversed']), ('invoice_date_due', 'in', target_dates), - ('date_terima_tukar_faktur', '!=', False), - ('partner_id', 'in' , [94603]) - ], limit=5) + ('date_terima_tukar_faktur', '!=', False) + ]) _logger.info(f"Invoices: {invoices}") invoices = invoices.filtered( -- cgit v1.2.3 From 31a7f35e3c179b7f7ed3dcf764c7e834af559283 Mon Sep 17 00:00:00 2001 From: it-fixcomart Date: Thu, 4 Sep 2025 11:21:39 +0700 Subject: fix finance note open lock --- indoteknik_custom/views/refund_sale_order.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index 20a07aa3..0c6cd371 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -218,8 +218,8 @@ - - + + -- cgit v1.2.3 From 0a1f22cac507ee7e9975f1a68f79bccdf179c9fd Mon Sep 17 00:00:00 2001 From: Miqdad Date: Fri, 5 Sep 2025 09:07:23 +0700 Subject: add image --- indoteknik_custom/models/stock_move.py | 1 + indoteknik_custom/views/stock_picking.xml | 100 ++++++++++++++++++------------ 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 90ab30a4..d4106830 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -15,6 +15,7 @@ class StockMove(models.Model): barcode = fields.Char(string='Barcode', related='product_id.barcode') vendor_id = fields.Many2one('res.partner' ,string='Vendor') hold_outgoingg = fields.Boolean('Hold Outgoing', default=False) + product_image_128 = fields.Image('Product Image', related='product_id.image_1920') # @api.model_create_multi # def create(self, vals_list): diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index b3f0ce9f..e230bccc 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -8,7 +8,7 @@ final_seq asc - + @@ -20,9 +20,11 @@ - + - + @@ -50,11 +52,11 @@ type="object" attrs="{'invisible': ['|', ('state', 'in', ['done']), ('approval_receipt_status', '=', 'pengajuan1')]}" /> - - - - - + + + + + + + + @@ -105,7 +112,8 @@ - + @@ -133,7 +141,7 @@ 1 - + @@ -141,7 +149,8 @@ - + + - - + + - - + + - + - - + + - + @@ -220,7 +235,8 @@ - - -- cgit v1.2.3 From 4bd34e21d8d4dc3b2f688e181fb05c6359ac1f43 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Sat, 6 Sep 2025 11:29:08 +0700 Subject: fix manufacture in stock move line & done --- indoteknik_custom/models/stock_move.py | 3 +-- indoteknik_custom/views/stock_move_line.xml | 9 +++++---- indoteknik_custom/views/stock_picking.xml | 7 ++++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index 9ec36fcd..24d405a6 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -18,8 +18,7 @@ class StockMove(models.Model): barcode = fields.Char(string='Barcode', related='product_id.barcode') vendor_id = fields.Many2one('res.partner' ,string='Vendor') hold_outgoingg = fields.Boolean('Hold Outgoing', default=False) - product_image= fields.Image('Product Image', related='product_id.image_1920') - + product_image = fields.Binary(related="product_id.image_128", string="Product Image", readonly = True) # @api.model_create_multi # def create(self, vals_list): # moves = super(StockMove, self).create(vals_list) diff --git a/indoteknik_custom/views/stock_move_line.xml b/indoteknik_custom/views/stock_move_line.xml index 757d2522..94c0bf53 100644 --- a/indoteknik_custom/views/stock_move_line.xml +++ b/indoteknik_custom/views/stock_move_line.xml @@ -3,18 +3,19 @@ Stock Move Line stock.move.line - + + - + - + Stock Move Line stock.move.line - + diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index c8aa6454..50c5f261 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -99,7 +99,7 @@ attrs="{'invisible': [('state_approve_md', 'not in', ['waiting'])]}" /> - @@ -140,6 +140,11 @@ 1 + + + + -- cgit v1.2.3 From 4cdb3a7b89d5e93449fadafec015e80dad1cf47f Mon Sep 17 00:00:00 2001 From: AndriFP Date: Sat, 6 Sep 2025 14:04:27 +0700 Subject: (andri) add validasi di SO dan respartner --- indoteknik_custom/models/res_partner.py | 16 +++++++++------- indoteknik_custom/models/sale_order.py | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 80fe643b..b5ce9266 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -183,13 +183,6 @@ class ResPartner(models.Model): is_cbd_locked = fields.Boolean("Locked to CBD?", default=False, tracking=True, help="Jika dicentang, maka partner ini terkunci pada payment term CBD karena memiliki invoice yang sudah jatuh tempo lebih dari 30 hari.") - # centang manual is_cbd_locked jika payment term diubah ke CBD - # @api.onchange('is_cbd_locked') - # def _onchange_is_cbd_locked(self): - # if self.is_cbd_locked: - # cbd_term = self.env['account.payment.term'].browse(26) - # if cbd_term: - # self.property_payment_term_id = cbd_term.id @api.model def _default_payment_term(self): @@ -201,6 +194,15 @@ class ResPartner(models.Model): default=_default_payment_term, tracking=3 ) + @api.constrains('property_payment_term_id', 'is_cbd_locked') + def _check_cbd_lock_partner(self): + cbd_term = self.env['account.payment.term'].browse(26) + for rec in self: + if rec.is_cbd_locked and rec.property_payment_term_id and rec.property_payment_term_id != cbd_term: + raise ValidationError( + "Partner ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." + ) + @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", "kecamatan_id") def _alamat_lengkap_text(self): diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 992c1a5d..8a595d8e 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -404,6 +404,23 @@ class SaleOrder(models.Model): for order in self: order.partner_is_cbd_locked = order.partner_id.is_cbd_locked + @api.onchange('payment_term_id') + def _onchange_partner_payment_term(self): + cbd_term = self.env['account.payment.term'].browse(26) + for rec in self: + if rec.partner_id and rec.partner_id.is_cbd_locked and cbd_term: + rec.payment_term_id = cbd_term + + @api.constrains('payment_term_id', 'partner_id', 'state') + def _check_cbd_lock_sale_order(self): + cbd_term = self.env['account.payment.term'].browse(26) + for rec in self: + if rec.state == 'draft' and rec.partner_id.is_cbd_locked: + if rec.payment_term_id and rec.payment_term_id != cbd_term: + raise ValidationError( + "Customer ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." + ) + @api.depends('invoice_ids.payment_state', 'invoice_ids.amount_total', 'invoice_ids.amount_residual') def _compute_payment_state_custom(self): for order in self: -- cgit v1.2.3 From f2adf9ad9ed7491a6ad5422d1236761e7d42c82f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 8 Sep 2025 12:30:59 +0700 Subject: remove image in tree view --- indoteknik_custom/views/stock_picking.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml index 50c5f261..fc8be790 100644 --- a/indoteknik_custom/views/stock_picking.xml +++ b/indoteknik_custom/views/stock_picking.xml @@ -99,11 +99,11 @@ attrs="{'invisible': [('state_approve_md', 'not in', ['waiting'])]}" /> - - + --> -- cgit v1.2.3 From 6188090965c5381fa120268a024a486e62056505 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 8 Sep 2025 15:05:19 +0700 Subject: hilangin validasi sementara --- indoteknik_custom/models/tukar_guling_po.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index f2f37606..c65ac286 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -441,8 +441,8 @@ class TukarGulingPO(models.Model): ('state', '!=', 'cancel'), ], limit=1) - if existing_tukar_guling: - raise UserError("BU ini sudah pernah diretur oleh dokumen %s." % existing_tukar_guling.name) + # if existing_tukar_guling: + # raise UserError("BU ini sudah pernah diretur oleh dokumen %s." % existing_tukar_guling.name) picking = self.operations pick_id = self.operations.picking_type_id.id -- cgit v1.2.3 From 7a34ad0965e08d1428c700f09a49f30f17c1996c Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 8 Sep 2025 15:08:54 +0700 Subject: Balikin --- indoteknik_custom/models/tukar_guling_po.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index c65ac286..f2f37606 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -441,8 +441,8 @@ class TukarGulingPO(models.Model): ('state', '!=', 'cancel'), ], limit=1) - # if existing_tukar_guling: - # raise UserError("BU ini sudah pernah diretur oleh dokumen %s." % existing_tukar_guling.name) + if existing_tukar_guling: + raise UserError("BU ini sudah pernah diretur oleh dokumen %s." % existing_tukar_guling.name) picking = self.operations pick_id = self.operations.picking_type_id.id -- cgit v1.2.3 From 69c9579636182d81b1b6da010f29f5efda6f88a7 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 8 Sep 2025 15:13:38 +0700 Subject: Fix oauth google --- indoteknik_api/controllers/api_v1/user.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index dde30fec..c75e4954 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -89,7 +89,8 @@ class User(controller.Controller): 'name': name, 'login': email, 'oauth_provider_id': request.env.ref('auth_oauth.provider_google').id, - 'sel_groups_1_9_10': 9 + 'sel_groups_1_9_10': 9, + 'active': True } user = request.env['res.users'].create(user_data) -- cgit v1.2.3 From 03db5f5bfd027fceeb0733bbb51e95e03c43d2cd Mon Sep 17 00:00:00 2001 From: Miqdad Date: Mon, 8 Sep 2025 16:20:28 +0700 Subject: copy false PO refund --- indoteknik_custom/models/purchase_order.py | 2 +- indoteknik_custom/models/refund_sale_order.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 50913a80..18811b85 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -66,7 +66,7 @@ class PurchaseOrder(models.Model): sale_order = fields.Char(string='Sale Order') matches_so = fields.Many2many('sale.order', string='Matches SO', compute='_compute_matches_so') is_create_uangmuka = fields.Boolean(string='Uang Muka?') - move_id = fields.Many2one('account.move', string='Journal Entries Uang Muka', domain=[('move_type', '=', 'entry')]) + move_id = fields.Many2one('account.move', string='Journal Entries Uang Muka', domain=[('move_type', '=', 'entry')], copy=False) logbook_bill_id = fields.Many2one('report.logbook.bill', string='Logbook Bill') status_printed = fields.Selection([ ('not_printed', 'Belum Print'), diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 731d8e41..9ab18f27 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -76,6 +76,7 @@ class RefundSaleOrder(models.Model): transfer_move_id = fields.Many2one( 'account.move', string="Journal Payment", + copy=False, help="Pilih transaksi salah transfer dari jurnal Uang Muka (journal_id=11) yang tidak terkait SO." ) -- cgit v1.2.3 From 1767a569e88e8254fdbefdfaf6be6045f1f5235f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 11:45:39 +0700 Subject: apt request done --- indoteknik_custom/models/approval_payment_term.py | 4 ++-- indoteknik_custom/views/approval_payment_term.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/approval_payment_term.py b/indoteknik_custom/models/approval_payment_term.py index 8618856a..85fd1613 100644 --- a/indoteknik_custom/models/approval_payment_term.py +++ b/indoteknik_custom/models/approval_payment_term.py @@ -69,8 +69,8 @@ class ApprovalPaymentTerm(models.Model): return res def _track_changes_for_user_688(self, vals, old_values_dict): - if self.env.user.id != 688: - return + # if self.env.user.id != 688: + # return tracked_fields = {"blocking_stage", "warning_stage", "property_payment_term_id"} diff --git a/indoteknik_custom/views/approval_payment_term.xml b/indoteknik_custom/views/approval_payment_term.xml index 5c130f3f..b0b99689 100644 --- a/indoteknik_custom/views/approval_payment_term.xml +++ b/indoteknik_custom/views/approval_payment_term.xml @@ -7,7 +7,7 @@ - + -- cgit v1.2.3 From e3c9d12ca2356493bb75c7362d0da54280889828 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 12:22:07 +0700 Subject: dunning done --- indoteknik_custom/models/dunning_run.py | 2 ++ indoteknik_custom/views/dunning_run.xml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 5a6aebac..eb6f06dc 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -31,6 +31,7 @@ class DunningRun(models.Model): description = fields.Char(string='Description') comment = fields.Char(string='Comment') grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") + is_paid = fields.Boolean(string='Sudah Bayar?') def _compute_grand_total(self): for record in self: @@ -149,4 +150,5 @@ class DunningRunLine(models.Model): total_amt = fields.Float(string='Total Amount') open_amt = fields.Float(string='Open Amount') due_date = fields.Date(string='Due Date') + payment_term = fields.Many2one('account.payment.term', related='invoice_id.invoice_payment_term_id', string='Payment Term') diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index f624c42e..7623666b 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -25,6 +25,7 @@ + @@ -74,6 +75,7 @@ + -- cgit v1.2.3 From 32d0ca72aa38701747794dab06e7fb98b6f31489 Mon Sep 17 00:00:00 2001 From: AndriFP <113114423+andrifp@users.noreply.github.com> Date: Wed, 10 Sep 2025 13:42:34 +0700 Subject: (andri) rev validasi --- indoteknik_custom/models/res_partner.py | 4 ++-- indoteknik_custom/models/sale_order.py | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index b5ce9266..0c932dbe 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -196,9 +196,9 @@ class ResPartner(models.Model): @api.constrains('property_payment_term_id', 'is_cbd_locked') def _check_cbd_lock_partner(self): - cbd_term = self.env['account.payment.term'].browse(26) + # cbd_term = self.env['account.payment.term'].browse(26) for rec in self: - if rec.is_cbd_locked and rec.property_payment_term_id and rec.property_payment_term_id != cbd_term: + if rec.is_cbd_locked: raise ValidationError( "Partner ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." ) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 8a595d8e..89bf0d25 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -404,22 +404,22 @@ class SaleOrder(models.Model): for order in self: order.partner_is_cbd_locked = order.partner_id.is_cbd_locked - @api.onchange('payment_term_id') - def _onchange_partner_payment_term(self): - cbd_term = self.env['account.payment.term'].browse(26) - for rec in self: - if rec.partner_id and rec.partner_id.is_cbd_locked and cbd_term: - rec.payment_term_id = cbd_term + # @api.onchange('payment_term_id') + # def _onchange_partner_payment_term(self): + # cbd_term = self.env['account.payment.term'].browse(26) + # for rec in self: + # if rec.partner_id and rec.partner_id.is_cbd_locked and cbd_term: + # rec.payment_term_id = cbd_term @api.constrains('payment_term_id', 'partner_id', 'state') def _check_cbd_lock_sale_order(self): - cbd_term = self.env['account.payment.term'].browse(26) + # cbd_term = self.env['account.payment.term'].browse(26) for rec in self: if rec.state == 'draft' and rec.partner_id.is_cbd_locked: - if rec.payment_term_id and rec.payment_term_id != cbd_term: - raise ValidationError( - "Customer ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." - ) + # if rec.payment_term_id and rec.payment_term_id != cbd_term: + raise ValidationError( + "Customer ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." + ) @api.depends('invoice_ids.payment_state', 'invoice_ids.amount_total', 'invoice_ids.amount_residual') def _compute_payment_state_custom(self): -- cgit v1.2.3 From 4ce4b37fa551e1059cdb5f64f98c53d4289d3268 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 16:04:39 +0700 Subject: dunning done --- indoteknik_custom/models/approval_payment_term.py | 3 ++- indoteknik_custom/models/dunning_run.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/approval_payment_term.py b/indoteknik_custom/models/approval_payment_term.py index 85fd1613..61339b99 100644 --- a/indoteknik_custom/models/approval_payment_term.py +++ b/indoteknik_custom/models/approval_payment_term.py @@ -106,7 +106,8 @@ class ApprovalPaymentTerm(models.Model): if changes: timestamp = fields.Datetime.now().strftime('%Y-%m-%d %H:%M:%S') - rec.change_log_688 = f"{timestamp} - Perubahan oleh Widya:\n" + "\n".join(changes) + user = self.env.user + rec.change_log_688 = f"{timestamp} - Perubahan oleh {user.name}:\n" + "\n".join(changes) @staticmethod diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index eb6f06dc..40e5f71e 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -1,6 +1,6 @@ from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError -from datetime import timedelta +from datetime import timedelta, date import logging @@ -32,7 +32,17 @@ class DunningRun(models.Model): comment = fields.Char(string='Comment') grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") is_paid = fields.Boolean(string='Sudah Bayar?') - + tanggal_pembayaran = fields.Date( + string='Tanggal Pembayaran', + compute="_compute_tanggal_pembayaran", + readonly=True, + ) + + @api.depends('is_paid') + def _compute_tanggal_pembayaran(self): + today = fields.Date.context_today(self) + for rec in self: + rec.tanggal_pembayaran = today if rec.is_paid else False def _compute_grand_total(self): for record in self: grand_total = 0 -- cgit v1.2.3 From 7887ebd226edebbb3261c802c38f0d0925a17f91 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 16:04:47 +0700 Subject: dunning done --- indoteknik_custom/views/dunning_run.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 7623666b..7c5f4af6 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -76,6 +76,7 @@ + -- cgit v1.2.3 From 8aceb84b2cf029308903b39bfe139a05ea8f73f6 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 16:08:34 +0700 Subject: dunning done --- indoteknik_custom/models/dunning_run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 40e5f71e..557eacef 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -43,6 +43,7 @@ class DunningRun(models.Model): today = fields.Date.context_today(self) for rec in self: rec.tanggal_pembayaran = today if rec.is_paid else False + def _compute_grand_total(self): for record in self: grand_total = 0 -- cgit v1.2.3 From e276a3bbf0a2726cbfa6bb5606d2dfbfe1e03143 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Wed, 10 Sep 2025 18:34:49 +0700 Subject: Remove tanggal bayar and is paid --- indoteknik_custom/models/dunning_run.py | 12 ------------ indoteknik_custom/views/dunning_run.xml | 3 +-- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 557eacef..9feea1d1 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -31,18 +31,6 @@ class DunningRun(models.Model): description = fields.Char(string='Description') comment = fields.Char(string='Comment') grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") - is_paid = fields.Boolean(string='Sudah Bayar?') - tanggal_pembayaran = fields.Date( - string='Tanggal Pembayaran', - compute="_compute_tanggal_pembayaran", - readonly=True, - ) - - @api.depends('is_paid') - def _compute_tanggal_pembayaran(self): - today = fields.Date.context_today(self) - for rec in self: - rec.tanggal_pembayaran = today if rec.is_paid else False def _compute_grand_total(self): for record in self: diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 7c5f4af6..fbd9dc72 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -75,8 +75,7 @@ - - + -- cgit v1.2.3 From 6a56c1d6bfa09bf5f4d190e3f8fee5265aa01c3f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 11 Sep 2025 08:12:13 +0700 Subject: remove is paid and tanggal bayar --- indoteknik_custom/models/dunning_run.py | 6 ------ indoteknik_custom/views/dunning_run.xml | 2 -- 2 files changed, 8 deletions(-) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 557eacef..5dba3f7d 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -31,12 +31,6 @@ class DunningRun(models.Model): description = fields.Char(string='Description') comment = fields.Char(string='Comment') grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") - is_paid = fields.Boolean(string='Sudah Bayar?') - tanggal_pembayaran = fields.Date( - string='Tanggal Pembayaran', - compute="_compute_tanggal_pembayaran", - readonly=True, - ) @api.depends('is_paid') def _compute_tanggal_pembayaran(self): diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 7c5f4af6..1cac744a 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -75,8 +75,6 @@ - - -- cgit v1.2.3 From 142f1a37b0d73ea847345428acc4224ff6e49419 Mon Sep 17 00:00:00 2001 From: Azka Nathan Date: Thu, 11 Sep 2025 08:57:04 +0700 Subject: purchase report --- indoteknik_custom/__manifest__.py | 2 + indoteknik_custom/report/purchase_report.xml | 162 +++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 indoteknik_custom/report/purchase_report.xml diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 31685005..09a3aa6f 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -166,6 +166,7 @@ 'report/report_invoice.xml', 'report/report_picking.xml', 'report/report_sale_order.xml', + 'report/purchase_report.xml', 'views/vendor_sla.xml', 'views/coretax_faktur.xml', 'views/public_holiday.xml', @@ -177,6 +178,7 @@ 'views/tukar_guling_po.xml', # 'views/refund_sale_order.xml', 'views/update_date_planned_po_wizard_view.xml', + # 'views/reimburse.xml', ], 'demo': [], 'css': [], diff --git a/indoteknik_custom/report/purchase_report.xml b/indoteknik_custom/report/purchase_report.xml new file mode 100644 index 00000000..9d7f4028 --- /dev/null +++ b/indoteknik_custom/report/purchase_report.xml @@ -0,0 +1,162 @@ + + + + + + Purchase Order (Website) + purchase.order + qweb-pdf + indoteknik_custom.report_purchaseorder_website + indoteknik_custom.report_purchaseorder_website + + ('PO - %s - %s' % (object.partner_id.name, object.name)) + + + report + + + + + + + + + + -- cgit v1.2.3 From 6c9c60324674ce1a0b46a863a6ae0ca0e8042d2f Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 11 Sep 2025 09:17:17 +0700 Subject: remove tanggal bayar --- indoteknik_custom/models/dunning_run.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py index 5dba3f7d..9feea1d1 100644 --- a/indoteknik_custom/models/dunning_run.py +++ b/indoteknik_custom/models/dunning_run.py @@ -32,12 +32,6 @@ class DunningRun(models.Model): comment = fields.Char(string='Comment') grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total") - @api.depends('is_paid') - def _compute_tanggal_pembayaran(self): - today = fields.Date.context_today(self) - for rec in self: - rec.tanggal_pembayaran = today if rec.is_paid else False - def _compute_grand_total(self): for record in self: grand_total = 0 -- cgit v1.2.3 From 777f284f1811a3127d98cf5bb49934dc04e75002 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 11 Sep 2025 10:32:54 +0700 Subject: hide efaktur --- indoteknik_custom/views/dunning_run.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml index 1cac744a..9c28591c 100644 --- a/indoteknik_custom/views/dunning_run.xml +++ b/indoteknik_custom/views/dunning_run.xml @@ -28,7 +28,7 @@ - + -- cgit v1.2.3 From d27561901fa2f0ab7534f255351e82459c6a531e Mon Sep 17 00:00:00 2001 From: AndriFP <113114423+andrifp@users.noreply.github.com> Date: Thu, 11 Sep 2025 10:45:58 +0700 Subject: (andri) fix --- indoteknik_custom/models/res_partner.py | 8 -------- indoteknik_custom/views/res_partner.xml | 2 +- indoteknik_custom/views/sale_order.xml | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py index 0c932dbe..36570e8f 100644 --- a/indoteknik_custom/models/res_partner.py +++ b/indoteknik_custom/models/res_partner.py @@ -194,14 +194,6 @@ class ResPartner(models.Model): default=_default_payment_term, tracking=3 ) - @api.constrains('property_payment_term_id', 'is_cbd_locked') - def _check_cbd_lock_partner(self): - # cbd_term = self.env['account.payment.term'].browse(26) - for rec in self: - if rec.is_cbd_locked: - raise ValidationError( - "Partner ini terkunci ke CBD, hanya boleh pakai Payment Term CBD." - ) @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id", "kecamatan_id") diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml index 7541df35..7d5be3b7 100644 --- a/indoteknik_custom/views/res_partner.xml +++ b/indoteknik_custom/views/res_partner.xml @@ -108,7 +108,7 @@ - 0 + 1 1 diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 236a8b14..5f1a6117 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -47,7 +47,7 @@ -- cgit v1.2.3 From c5e14063c50ae06b829eca0415b9b14b03ccb0b6 Mon Sep 17 00:00:00 2001 From: AndriFP <113114423+andrifp@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:07:29 +0700 Subject: (andri) fix --- indoteknik_custom/models/sale_order.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index d0fd7f48..dbe6d789 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -403,12 +403,6 @@ class SaleOrder(models.Model): for order in self: order.partner_is_cbd_locked = order.partner_id.is_cbd_locked - # @api.onchange('payment_term_id') - # def _onchange_partner_payment_term(self): - # cbd_term = self.env['account.payment.term'].browse(26) - # for rec in self: - # if rec.partner_id and rec.partner_id.is_cbd_locked and cbd_term: - # rec.payment_term_id = cbd_term @api.constrains('payment_term_id', 'partner_id', 'state') def _check_cbd_lock_sale_order(self): -- cgit v1.2.3 From ee6c5f572f06e5fde497fc3aed5d78c3f0d7d389 Mon Sep 17 00:00:00 2001 From: Miqdad Date: Thu, 11 Sep 2025 17:13:59 +0700 Subject: Gudang pameran --- indoteknik_custom/models/sale_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 9952af9a..67e712d1 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -2115,8 +2115,8 @@ class SaleOrder(models.Model): if self.payment_term_id.id == 31 and self.total_percent_margin < 25: raise UserError("Jika ingin menggunakan Tempo 90 Hari maka margin harus di atas 25%") - if self.warehouse_id.id != 8 and self.warehouse_id.id != 10: # GD Bandengan - raise UserError('Gudang harus Bandengan') + if self.warehouse_id.id != 8 and self.warehouse_id.id != 10 and self.warehouse_id.id != 12: # GD Bandengan / Pameran + raise UserError('Gudang harus Bandengan atau Pameran') if self.state not in ['draft', 'sent']: raise UserError("Status harus draft atau sent") -- cgit v1.2.3 From 51e77c4968cbc0e577e161a38407bb9f291a6f62 Mon Sep 17 00:00:00 2001 From: AndriFP <113114423+andrifp@users.noreply.github.com> Date: Thu, 11 Sep 2025 18:43:25 +0700 Subject: (andri) fix --- indoteknik_custom/models/sale_order.py | 16 ++++++++-------- indoteknik_custom/views/sale_order.xml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 76d4d7e7..42f58d2b 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -393,15 +393,15 @@ class SaleOrder(models.Model): ('paid', 'Full Paid'), ('no_invoice', 'No Invoice'), ], string="Payment Status Invoice", compute="_compute_payment_state_custom", store=False) - partner_is_cbd_locked = fields.Boolean( - string="Partner Locked CBD", - compute="_compute_partner_is_cbd_locked" - ) + # partner_is_cbd_locked = fields.Boolean( + # string="Partner Locked CBD", + # compute="_compute_partner_is_cbd_locked" + # ) - @api.depends('partner_id.is_cbd_locked') - def _compute_partner_is_cbd_locked(self): - for order in self: - order.partner_is_cbd_locked = order.partner_id.is_cbd_locked + # @api.depends('partner_id.is_cbd_locked') + # def _compute_partner_is_cbd_locked(self): + # for order in self: + # order.partner_is_cbd_locked = order.partner_id.is_cbd_locked @api.constrains('payment_term_id', 'partner_id', 'state') diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 326fd560..542ffa0c 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -41,7 +41,7 @@ string="Refund" class="btn-primary" /> - +