diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-07-23 14:50:10 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-07-23 14:50:10 +0700 |
| commit | deb60713ed39979b34083ee094de79fa3afac3b8 (patch) | |
| tree | b1648b3b7822034fb893b82e78f16769c5db54aa /indoteknik_custom/models/sale_order.py | |
| parent | c667a8699762057c9e6191466a182ebb69cb66c7 (diff) | |
<hafid> Refund System
Diffstat (limited to 'indoteknik_custom/models/sale_order.py')
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 123 |
1 files changed, 122 insertions, 1 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 591951ca..8d40bfb5 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -356,6 +356,14 @@ class SaleOrder(models.Model): compute="_compute_eta_date_reserved", 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', + compute='_compute_advance_payment_move', + string='Advance Payment Move', + ) @api.depends('order_line.product_id', 'date_order') def _compute_et_products(self): @@ -3077,4 +3085,117 @@ class SaleOrder(models.Model): if any(field in vals for field in ["order_line", "client_order_ref"]): self._calculate_etrts_date() - return res
\ No newline at end of file + return res + + def button_refund(self): + self.ensure_one() + + invoice_ids = self.invoice_ids.filtered(lambda inv: inv.state != 'cancel') + + return { + 'name': 'Refund Sale Order', + 'type': 'ir.actions.act_window', + 'res_model': 'refund.sale.order', + 'view_mode': 'form', + 'target': 'current', + '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_ongkir': self.delivery_amt or 0.0, + 'default_bank': '', # bisa isi default bank kalau mau + 'default_account_name': '', + 'default_account_no': '', + 'default_refund_type': '', + }, + } + + def open_form_multi_create_refund(self): + if not self: + raise UserError("Tidak ada Sale Order yang dipilih.") + + partner_set = set(self.mapped('partner_id.id')) + if len(partner_set) > 1: + raise UserError("Tidak dapat membuat refund untuk Multi SO dengan Customer berbeda. Harus memiliki Customer yang sama.") + + invoice_status_set = set(self.mapped('invoice_status')) + 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.") + + 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')) + + return { + 'type': 'ir.actions.act_window', + 'name': 'Create Refund', + 'res_model': 'refund.sale.order', + 'view_mode': 'form', + 'target': 'current', + '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_ongkir': delivery_total, + 'default_bank': '', + 'default_account_name': '', + 'default_account_no': '', + 'default_refund_type': '', + } + } + + @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 { + 'type': 'ir.actions.act_window', + 'name': 'Refunds', + 'res_model': 'refund.sale.order', + 'view_mode': 'tree,form', + 'domain': [('sale_order_ids', 'in', [self.id])], + 'context': {'default_sale_order_ids': [self.id]}, + } + + def _compute_refund_ids(self): + for order in self: + refunds = self.env['refund.sale.order'].search([ + ('sale_order_ids', 'in', [order.id]) + ]) + order.refund_ids = refunds + + def _compute_refund_count(self): + for order in self: + order.refund_count = self.env['refund.sale.order'].search_count([ + ('sale_order_ids', 'in', order.id) + ]) + + @api.depends('invoice_ids') + def _compute_advance_payment_move(self): + for order in self: + move = self.env['account.move'].search([ + ('sale_id', '=', order.id), + ('journal_id', '=', 11), + ('state', '=', 'posted'), + ], limit=1, order="id desc") + order.advance_payment_move_id = move + + def action_open_advance_payment_move(self): + self.ensure_one() + if not self.advance_payment_move_id: + return + return { + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + 'res_id': self.advance_payment_move_id.id, + 'view_mode': 'form', + 'target': 'current', + }
\ No newline at end of file |
