diff options
Diffstat (limited to 'indoteknik_custom/models/sourcing_job_order.py')
| -rw-r--r-- | indoteknik_custom/models/sourcing_job_order.py | 126 |
1 files changed, 93 insertions, 33 deletions
diff --git a/indoteknik_custom/models/sourcing_job_order.py b/indoteknik_custom/models/sourcing_job_order.py index 6bb59c62..0e5334a8 100644 --- a/indoteknik_custom/models/sourcing_job_order.py +++ b/indoteknik_custom/models/sourcing_job_order.py @@ -89,11 +89,13 @@ class SourcingJobOrder(models.Model): @api.depends('eta_sales', 'eta_complete', 'create_date', 'state') def _compute_progress_status(self): for rec in self: - if rec.eta_sales: - # Ada tanggal expected - if rec.state == 'taken': - rec.progress_status = '🟡 On Track' - elif rec.state == 'done' and rec.eta_complete: + + if rec.state == 'cancel': + rec.progress_status = '⚫ Cancelled' + continue + + if rec.state == 'done': + if rec.eta_sales and rec.eta_complete: delta = (rec.eta_complete - rec.eta_sales).days if delta < 0: rec.progress_status = f'🟢 Early {abs(delta)} hari' @@ -101,22 +103,15 @@ class SourcingJobOrder(models.Model): rec.progress_status = '🔵 Ontime' else: rec.progress_status = f'🔴 Delay {delta} hari' - elif rec.state == 'cancel': - rec.progress_status = '⚫ Cancelled' - else: - rec.progress_status = '🟡 On Track' - else: - # Tidak ada ETA, hitung durasi - if rec.state == 'done' and rec.eta_complete: - if rec.create_date: - durasi = (rec.eta_complete - rec.create_date.date()).days - rec.progress_status = f'✅ Selesai dalam {durasi} hari' - else: - rec.progress_status = '✅ Selesai' - elif rec.state == 'cancel': - rec.progress_status = '⚫ Cancelled' + elif rec.create_date and rec.eta_complete: + durasi = (rec.eta_complete - rec.create_date.date()).days + rec.progress_status = f'✅ Selesai dalam {durasi} hari' else: - rec.progress_status = '🟡 On Track' + rec.progress_status = '✅ Selesai' + continue + + if rec.state in ['taken', 'partial', 'draft']: + rec.progress_status = '🟡 On Track' @api.depends('line_ids.price', 'line_ids.vendor_id') def _compute_has_price_in_lines(self): @@ -413,6 +408,7 @@ class SourcingJobOrderLine(models.Model): vals['show_salesperson'] = order.so_id.user_id.id rec = super().create(vals) + rec._check_line_limit() return rec def write(self, vals): @@ -427,8 +423,30 @@ class SourcingJobOrderLine(models.Model): res = super().write(vals) if 'state' in vals: self._update_parent_state() + self._check_line_limit() return res + def _check_line_limit(self): + for rec in self: + if not rec.order_id or not rec.order_id.so_id: + continue + + so = rec.order_id.so_id + + so_line_count = len(so.order_line) + + sourcing_lines = self.search([ + ('order_id', '=', rec.order_id.id), + ('state', '!=', 'cancel') + ]) + + if len(sourcing_lines) > so_line_count: + raise UserError( + f"Jumlah Sourcing Line tidak boleh melebihi Sales Order Line.\n\n" + f"Sales Order Line : {so_line_count}\n" + f"Sourcing Line : {len(sourcing_lines)}" + ) + def _update_parent_state(self): for rec in self: order = rec.order_id @@ -617,18 +635,40 @@ class SourcingJobOrderLine(models.Model): if line.state != 'sourcing': raise UserError("⚠️ Hanya line status 'Sourcing' yang bisa minta approval.") - if ( - not line.vendor_id - or not line.product_name_md - or not line.brand_id - or not line.price or line.price <= 0 - or not line.tax_id - or not line.subtotal or line.subtotal <= 0 - or not line.product_type - or not line.product_category - or not line.product_class - ): - raise UserError("❌ Lengkapi data sebelum Ask Approval sales") + missing_fields = [] + + if not line.vendor_id: + missing_fields.append("Vendor") + + if not line.product_name_md: + missing_fields.append("Product Name") + + if not line.brand_id: + missing_fields.append("Manufactures") + + if not line.price or line.price <= 0: + missing_fields.append("Price") + + if not line.tax_id: + missing_fields.append("Tax") + + if not line.subtotal or line.subtotal <= 0: + missing_fields.append("Subtotal") + + if not line.product_type: + missing_fields.append("Product Type") + + if not line.product_category: + missing_fields.append("Product Category") + + if not line.product_class: + missing_fields.append("Product Class") + + if missing_fields: + raise UserError( + "❌ Lengkapi data berikut sebelum Ask Approval Sales:\n- " + + "\n- ".join(missing_fields) + ) line.state = 'sent' @@ -730,7 +770,7 @@ class SourcingJobOrderLine(models.Model): 'consu': 'consu', } - product = ProductProduct.create({ + product = ProductProduct.with_context(from_sourcing_approval=True).create({ 'name': rec.product_name_md, 'default_code': rec.code or False, 'description': rec.descriptions_md or '', @@ -751,6 +791,11 @@ class SourcingJobOrderLine(models.Model): rec.product_id = product.id + self.env.user.notify_success( + message=f"Produk baru '{product.name}' berhasil dibuat dengan SKU {product.default_code}.", + title="Product Created" + ) + jakarta_tz = rec.order_id._get_jakarta_today() purchase_price = PurchasePricelist.search([ @@ -830,9 +875,24 @@ class SourcingJobOrderLine(models.Model): title="Approved" ) + so = self.mapped('so_id')[:1] + if so: + return { + 'type': 'ir.actions.act_window', + 'name': 'Sales Order', + 'res_model': 'sale.order', + 'view_mode': 'form', + 'res_id': so.id, + 'target': 'current', + } + return {'type': 'ir.actions.client', 'tag': 'reload'} def action_multi_approve(self): + so_ids = self.mapped('so_id').ids + + if len(set(so_ids)) > 1: + raise UserError("❌ Multi approve hanya bisa dilakukan jika semua line berasal dari Sales Order yang sama.") self.action_approve_approval() def action_reject_approval(self): |
