diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-08-22 11:08:08 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-08-22 11:08:08 +0700 |
| commit | a70798e97805e6c0befb6835abf6637dbac1dd8c (patch) | |
| tree | 1d7cbcf2a0a7c78b806300b5f14b607f0182f2f3 | |
| parent | bbc454fd6e13d12e9674769a555264f2c2343b5b (diff) | |
<hafid> ngambil bu out untuk retur
| -rw-r--r-- | indoteknik_custom/models/refund_sale_order.py | 148 | ||||
| -rw-r--r-- | indoteknik_custom/views/refund_sale_order.xml | 9 |
2 files changed, 106 insertions, 51 deletions
diff --git a/indoteknik_custom/models/refund_sale_order.py b/indoteknik_custom/models/refund_sale_order.py index 2dc72f0f..4f41a002 100644 --- a/indoteknik_custom/models/refund_sale_order.py +++ b/indoteknik_custom/models/refund_sale_order.py @@ -141,6 +141,7 @@ class RefundSaleOrder(models.Model): string="Sisa Uang Masuk", help="Sisa uang masuk yang masih bisa direfund (hanya berlaku untuk 1 SO)", ) + show_return_alert = fields.Boolean(compute="_compute_show_return_alert") @api.model def create(self, vals): @@ -155,6 +156,8 @@ class RefundSaleOrder(models.Model): if vals.get('name', 'New') == 'New': vals['name'] = self.env['ir.sequence'].next_by_code('refund.sale.order') or 'New' + + res = super().create(vals) vals['created_date'] = fields.Date.context_today(self) vals['create_uid'] = self.env.user.id @@ -176,11 +179,11 @@ 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 invoice_ids and refund_type and refund_type not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half', 'retur']: + raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur jika ada invoice") - if not invoice_ids and refund_type and refund_type in ['uang', 'barang_kosong_sebagian', 'retur_half']: - raise UserError("Refund type Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian Hanya Bisa dipilih Jika Ada Invoice") + if not invoice_ids and refund_type and refund_type in ['uang', 'barang_kosong_sebagian']: + raise UserError("Refund type Lebih Bayar dan Barang Kosong 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) @@ -200,23 +203,9 @@ class RefundSaleOrder(models.Model): raise UserError("❌ Tidak ada barang yang tidak Terkirim/Kosong di SO 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'.") - - refund = refund_type in ['retur', 'retur_half'] - if refund and so_ids: - so = self.env['sale.order'].browse(so_ids) - pickings = self.env['stock.picking'].search([ - ('state', '=', 'done'), - ('picking_type_id', '=', 73), - ('sale_id', 'in', so_ids) - ]) - if not pickings: - raise ValidationError(f"SO {', '.join(so.mapped('name'))} tidak melakukan retur barang.") - - if refund_type == 'retur_half' and not invoice_ids: - raise ValidationError(f"SO {', '.join(so.mapped('name'))} belum memiliki invoice untuk Retur Sebagian.") - + if not so_ids and refund_type != 'salah_transfer': + raise ValidationError("Jika tidak ada Sales Order yang dipilih, maka Tipe Refund hanya boleh 'Salah Transfer'.") + 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')) @@ -229,8 +218,7 @@ class RefundSaleOrder(models.Model): total_uang_muka = sum(moves.mapped('amount_total_signed')) 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) + vals['uang_masuk'] = uang_masuk 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 @@ -320,26 +308,12 @@ class RefundSaleOrder(models.Model): else: invoice_ids = rec.invoice_ids.ids - if invoice_ids and vals.get('refund_type', rec.refund_type) not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half']: - raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian jika ada invoice") + if invoice_ids and vals.get('refund_type', rec.refund_type) not in ['uang', 'barang_kosong_sebagian', 'barang_kosong', 'retur_half', 'retur']: + raise UserError("Refund type Hanya Bisa Lebih Bayar, Barang Kosong Sebagian, atau Retur jika ada invoice") - if not invoice_ids and vals.get('refund_type', rec.refund_type) in ['uang', 'barang_kosong_sebagian', 'retur_half']: - raise UserError("Refund type Lebih Bayar, Barang Kosong Sebagian, atau Retur Sebagian Hanya Bisa dipilih Jika Ada Invoice") + if not invoice_ids and vals.get('refund_type', rec.refund_type) in ['uang', 'barang_kosong_sebagian']: + raise UserError("Refund type Lebih Bayar, Barang Kosong Sebagian, atau Retur Hanya Bisa dipilih Jika Ada Invoice") - if refund_type in ['retur', 'retur_half'] and so_ids: - so = self.env['sale.order'].browse(so_ids) - pickings = self.env['stock.picking'].search([ - ('state', '=', 'done'), - ('picking_type_id', '=', 73), - ('sale_id', 'in', so_ids) - ]) - - if not pickings: - raise ValidationError(f"SO {', '.join(so.mapped('name'))} tidak melakukan retur barang.") - - 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', 'amount_refund']): total_invoice = sum(self.env['account.move'].browse(invoice_ids).mapped('amount_total_signed')) vals['total_invoice'] = total_invoice @@ -491,19 +465,53 @@ class RefundSaleOrder(models.Model): line_vals = [] StockPicking = self.env['stock.picking'] for so in self.sale_order_ids: - pickings = StockPicking.search([ + # BU/SRT + pickings_srt = StockPicking.search([ ('state', '=', 'done'), ('picking_type_id', '=', 73), ('sale_id', 'in', so.ids) ]) - - for picking in pickings: - for move in picking.move_lines: - line_vals.append((0, 0, { - 'product_id': move.product_id.id, - 'quantity': move.product_uom_qty, - 'reason': '', - })) + # BU/ORT + pickings_ort = StockPicking.search([ + ('state', '=', 'done'), + ('picking_type_id', '=', 74), + ('sale_id', 'in', so.ids) + ]) + if not pickings_ort and not pickings_srt: + # BU/OUT + product_out = StockPicking.search([ + ('state', '=', 'done'), + ('picking_type_id', '=', 29), + ('sale_id', 'in', so.ids) + ]) + for picking in product_out: + for move in picking.move_lines: + line_vals.append((0, 0, { + 'product_id': move.product_id.id, + 'product_from': picking.name, + 'quantity': move.product_uom_qty, + 'reason': '', + })) + + has_bu_pick = any(p.picking_type_id.id == 30 for p in so.picking_ids) + if not has_bu_pick: + for picking in pickings_srt: + for move in picking.move_lines: + line_vals.append((0, 0, { + 'product_id': move.product_id.id, + 'product_from': picking.name, + 'quantity': move.product_uom_qty, + 'reason': '', + })) + else: + for picking in pickings_ort: + for move in picking.move_lines: + line_vals.append((0, 0, { + 'product_id': move.product_id.id, + 'product_from': picking.name, + 'quantity': move.product_uom_qty, + 'reason': '', + })) self.line_ids = line_vals @@ -598,6 +606,18 @@ class RefundSaleOrder(models.Model): def action_ask_approval(self): for rec in self: + if rec.refund_type in ['retur', 'retur_half']: + so = rec.sale_order_ids + if so: + retur_done = self.env['stock.picking'].search_count([ + ('sale_id', '=', so.id), + ('picking_type_id', 'in', [73, 74]), + ('state', '=', 'done') + ]) + if retur_done == 0: + raise ValidationError( + f"⚠️ SO {so.name} memiliki refund tipe Retur. Selesaikan pengajuan retur untuk melanjutkan refund" + ) if rec.status == 'draft': rec.status = 'pengajuan1' @@ -611,6 +631,19 @@ class RefundSaleOrder(models.Model): now = datetime.now(jakarta_tz).replace(tzinfo=None) for rec in self: + if rec.refund_type in ['retur', 'retur_half']: + so = rec.sale_order_ids + if so: + retur_done = self.env['stock.picking'].search_count([ + ('sale_id', '=', so.id), + ('picking_type_id', 'in', [73, 74]), + ('state', '=', 'done') + ]) + if retur_done == 0: + raise ValidationError( + f"⚠️ SO {so.name} memiliki refund tipe Retur. Selesaikan retur untuk melanjutkan refund" + ) + user_name = self.env.user.name if not rec.status or rec.status == 'draft': @@ -824,6 +857,21 @@ class RefundSaleOrder(models.Model): for rec in self: rec.sale_order_count = len(rec.sale_order_ids) + def _compute_show_return_alert(self): + for rec in self: + retur_ort = self.env['stock.picking'].search([ + ('state', '=', 'done'), + ('picking_type_id', '=', 74), + ('sale_id', 'in', rec.sale_order_ids.ids) + ]) + + retur_srt = self.env['stock.picking'].search([ + ('state', '=', 'done'), + ('picking_type_id', '=', 73), + ('sale_id', 'in', rec.sale_order_ids.ids) + ]) + rec.show_return_alert = not retur_ort and not retur_srt + class RefundSaleOrderLine(models.Model): _name = 'refund.sale.order.line' _description = 'Refund Sales Order Line' diff --git a/indoteknik_custom/views/refund_sale_order.xml b/indoteknik_custom/views/refund_sale_order.xml index dd47c2ab..3c60cc57 100644 --- a/indoteknik_custom/views/refund_sale_order.xml +++ b/indoteknik_custom/views/refund_sale_order.xml @@ -79,6 +79,13 @@ statusbar_visible="draft,pengajuan1,pengajuan2,pengajuan3,refund" attrs="{'invisible': [('status', '=', 'reject')]}" /> </header> + <xpath expr="//sheet" position="inside"> + <field name="show_return_alert" invisible="1"/> + <div class="alert alert-info" role="alert" + attrs="{'invisible': [('show_return_alert', '=', False)]}"> + ⚠️ SO belum melakukan retur barang. Silakan buat pengajuan retur. + </div> + </xpath> <sheet> <div class="oe_button_box" name="button_box"> <button name="action_open_journal_refund" @@ -118,7 +125,7 @@ <field name="note_refund" attrs="{'readonly': [('is_locked', '=', True)]}"/> </group> <group> - <field name="uang_masuk" readonly="1"/> + <field name="uang_masuk" attrs="{'readonly': [('refund_type', '!=', 'salah_transfer')]}"/> <field name="total_invoice" readonly="1"/> <field name="ongkir" attrs="{'readonly': [('is_locked', '=', True)]}"/> <field name="amount_refund" attrs="{'readonly': [('is_locked', '=', True)]}"/> |
