diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-08-13 09:48:41 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-08-13 09:48:41 +0700 |
| commit | 7644260c8b660c71aa1f9232cb50acea551798c2 (patch) | |
| tree | bdbad5e360bd7d638b340c6d96d19dc8c7912d00 /indoteknik_custom/models/tukar_guling_po.py | |
| parent | d1e55b12466b6c93cc4a3e23dab59d3ce3795d45 (diff) | |
| parent | a2d087032e5b14901f4128c81b58143bcff4286f (diff) | |
<hafid> merging odoo-backup
Diffstat (limited to 'indoteknik_custom/models/tukar_guling_po.py')
| -rw-r--r-- | indoteknik_custom/models/tukar_guling_po.py | 117 |
1 files changed, 94 insertions, 23 deletions
diff --git a/indoteknik_custom/models/tukar_guling_po.py b/indoteknik_custom/models/tukar_guling_po.py index 92d8c9a6..cc1c79c0 100644 --- a/indoteknik_custom/models/tukar_guling_po.py +++ b/indoteknik_custom/models/tukar_guling_po.py @@ -54,6 +54,75 @@ class TukarGulingPO(models.Model): ('cancel', 'Cancel'), ], string='Status', default='draft', tracking=3) + val_bil_opt = fields.Selection([ + ('tanpa_cancel', 'Tanpa Cancel Bill'), + ('cancel_bill', 'Cancel Bill'), + ], tracking=3, string='Bill Option') + + is_has_bill = fields.Boolean('Has Bill?', compute='_compute_is_has_bill', readonly=True, default=False) + + bill_id = fields.Many2many('account.move', string='Bill Ref', readonly=True) + origin_po = fields.Many2one('purchase.order', string='Origin PO', compute='_compute_origin_po') + + @api.depends('origin', 'operations') + def _compute_origin_po(self): + for rec in self: + rec.origin_po = False + origin_str = rec.origin or rec.operations.origin + if origin_str: + so = self.env['purchase.order'].search([('name', '=', origin_str)], limit=1) + rec.origin_po = so.id if so else False + + @api.depends('origin', 'origin_po', 'vendor_id', 'line_ids.product_id') + def _compute_is_has_bill(self): + Move = self.env['account.move'] + for rec in self: + # reset + rec.is_has_bill = False + rec.bill_id = [(5, 0, 0)] + + product_ids = rec.line_ids.mapped('product_id').ids + if not product_ids: + continue + + # dasar: bill atau vendor credit note yang linennya mengandung produk TG + domain = [ + ('move_type', 'in', ['in_invoice', 'in_refund']), + ('state', 'not in', ['draft', 'cancel']), + ('invoice_line_ids.product_id', 'in', product_ids), + ] + + # batasi ke vendor sama (kalau ada) + if rec.vendor_id: + domain.append(('partner_id', '=', rec.vendor_id.id)) + + # bantu pembatasan ke asal dokumen + extra = [] + if rec.origin: + extra.append(('invoice_origin', 'ilike', rec.origin)) + if rec.origin_po: + # di Odoo 14, invoice line biasanya link ke purchase.line lewat purchase_line_id + extra.append(('invoice_line_ids.purchase_line_id.order_id', '=', rec.origin_po.id)) + + # OR-kan semua extra filter jika ada + if extra: + domain = domain + ['|'] * (len(extra) - 1) + extra + + bills = Move.search(domain).with_context(active_test=False) + + # --- Opsi 1: minimal salah satu produk TG muncul di bill (default) --- + rec.bill_id = [(6, 0, bills.ids)] + rec.is_has_bill = bool(bills) + + def set_opt(self): + if not self.val_bil_opt and self.is_has_bill == True: + raise UserError("Kalau sudah ada bill Return Bill Option harus diisi!") + for rec in self: + if rec.val_bil_opt == 'cancel_bill' and self.is_has_bill == True: + raise UserError("Tidak bisa mengubah Return karena sudah ada bill dan belum di cancel.") + elif rec.val_bil_opt == 'tanpa_cancel' and self.is_has_bill == True: + continue + @api.model def create(self, vals): # Generate sequence number @@ -74,19 +143,18 @@ class TukarGulingPO(models.Model): return res - @api.constrains('return_type', 'operations') - def _check_bill_on_revisi_po(self): - for record in self: - if record.return_type == 'revisi_po' and record.origin: - bills = self.env['account.move'].search([ - ('invoice_origin', 'ilike', record.origin), - ('move_type', '=', 'in_invoice'), # hanya vendor bill - ('state', 'not in', ['draft', 'cancel']) - ]) - if bills: - raise ValidationError( - _("Tidak bisa memilih Return Type 'Revisi PO' karena PO %s sudah dibuat vendor bill.") % record.origin - ) + # def _check_bill_on_revisi_po(self): + # for record in self: + # if record.return_type == 'revisi_po' and record.origin: + # bills = self.env['account.move'].search([ + # ('invoice_origin', 'ilike', record.origin), + # ('move_type', '=', 'in_invoice'), # hanya vendor bill + # ('state', 'not in', ['draft', 'cancel']) + # ]) + # if bills: + # raise ValidationError( + # _("Tidak bisa memilih Return Type 'Revisi PO' karena PO %s sudah dibuat vendor bill. Harus Cancel Jika ingin melanjutkan") % record.origin + # ) @api.onchange('operations') def _onchange_operations(self): @@ -102,6 +170,7 @@ class TukarGulingPO(models.Model): # Hanya update origin, jangan ubah lines if self.operations.origin: self.origin = self.operations.origin + self.origin_po = self.operations.group_id.id return if from_return_picking: @@ -281,7 +350,7 @@ class TukarGulingPO(models.Model): def write(self, vals): if self.operations.picking_type_id.id not in [75, 28]: raise UserError("❌ Tidak bisa retur bukan BU/INPUT atau BU/PUT!") - self._check_bill_on_revisi_po() + # self._check_bill_on_revisi_po() tipe = vals.get('return_type', self.return_type) if self.operations and self.operations.picking_type_id.id == 28 and tipe == 'tukar_guling': @@ -349,7 +418,7 @@ class TukarGulingPO(models.Model): def action_submit(self): self.ensure_one() - self._check_bill_on_revisi_po() + # self._check_bill_on_revisi_po() self._validate_product_lines() self._check_not_allow_tukar_guling_on_bu_input() @@ -385,7 +454,7 @@ class TukarGulingPO(models.Model): def action_approve(self): self.ensure_one() self._validate_product_lines() - self._check_bill_on_revisi_po() + # self._check_bill_on_revisi_po() self._check_not_allow_tukar_guling_on_bu_input() if not self.operations: @@ -399,20 +468,22 @@ class TukarGulingPO(models.Model): # Cek hak akses berdasarkan state for rec in self: if rec.state == 'approval_purchase': - if not rec.env.user.has_group('indoteknik_custom.group_role_sales'): - raise UserError("Hanya Sales Manager yang boleh approve tahap ini.") + if not rec.env.user.has_group('indoteknik_custom.group_role_purchasing'): + raise UserError("Hanya Purchasing yang boleh approve tahap ini.") rec.state = 'approval_finance' rec.date_purchase = now elif rec.state == 'approval_finance': if not rec.env.user.has_group('indoteknik_custom.group_role_fat'): - raise UserError("Hanya Finance Manager yang boleh approve tahap ini.") + raise UserError("Hanya Finance yang boleh approve tahap ini.") + # rec._check_bill_on_revisi_po() + rec.set_opt() rec.state = 'approval_logistic' rec.date_finance = now elif rec.state == 'approval_logistic': if not rec.env.user.has_group('indoteknik_custom.group_role_logistic'): - raise UserError("Hanya Logistic Manager yang boleh approve tahap ini.") + raise UserError("Hanya Logistic yang boleh approve tahap ini.") rec.state = 'approved' rec._create_pickings() rec.date_logistic = now @@ -427,7 +498,7 @@ class TukarGulingPO(models.Model): ('state', '=', 'done'), ('picking_type_id.id', '=', 76) ]) - if self.state == 'aproved' and prt: + if self.state == 'approved' and prt: self.state = 'done' # bu put rev po elif self.operations.picking_type_id.id == 75 and self.return_type == 'revisi_po': @@ -440,7 +511,7 @@ class TukarGulingPO(models.Model): ('state', '=', 'done'), ('picking_type_id.id', '=', 76) ]) - if self.state == 'aproved' and total_prt > 0 and prt == total_prt: + if self.state == 'approved' and total_prt > 0 and prt == total_prt: self.state = 'done' # bu put tukar guling elif self.operations.picking_type_id.id == 75 and self.return_type == 'tukar_guling': @@ -464,7 +535,7 @@ class TukarGulingPO(models.Model): user = self.env.user if not ( - user.has_group('indoteknik_custom.group_role_sales') or + user.has_group('indoteknik_custom.group_role_purchasing') or user.has_group('indoteknik_custom.group_role_fat') or user.has_group('indoteknik_custom.group_role_logistic') ): |
