diff options
Diffstat (limited to 'indoteknik_custom/models/purchase_order.py')
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 165 |
1 files changed, 160 insertions, 5 deletions
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index f924174a..9388ae4c 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -68,9 +68,12 @@ class PurchaseOrder(models.Model): ], string='Printed?', copy=False, tracking=True) date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') bills_dp_id = fields.Many2one('account.move', string='Bills DP') + bills_pelunasan_id = fields.Many2one('account.move', string='Bills Pelunasan') grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') total_margin_match = fields.Float(string='Total Margin Match', compute='_compute_total_margin_match') approve_by = fields.Many2one('res.users', string='Approve By') + exclude_incoming = fields.Boolean(string='Exclude Incoming', default=False, + help='Centang jika tidak mau masuk perhitungan Incoming Qty') def _compute_total_margin_match(self): for purchase in self: @@ -89,6 +92,89 @@ class PurchaseOrder(models.Model): else: order.grand_total = order.amount_total + def create_bill_pelunasan(self): + if not self.env.user.is_accounting: + raise UserError('Hanya Accounting yang bisa bikin bill dp') + + # Check for existing vendor bills with the same reference and partner + existing_bill = self.env['account.move'].search([ + ('ref', '=', self.name), + ('partner_id', '=', self.partner_id.id), + ('move_type', '=', 'in_invoice'), + ('state', 'not in', ['cancel', 'posted']) + ], limit=1) + + if existing_bill: + raise UserError(_('Duplicated vendor reference detected. You probably encoded twice the same vendor bill/credit note: %s') % existing_bill.name) + + current_date = datetime.utcnow() + data_bills = { + 'partner_id': self.partner_id.id, + 'partner_shipping_id': self.partner_id.id, + 'ref': self.name, + 'invoice_date': current_date, + 'date': current_date, + 'move_type': 'in_invoice' + } + + bills = self.env['account.move'].create([data_bills]) + + product_dp = self.env['product.product'].browse(229625) + + data_line_bills = [] + + move_line = self.env['account.move.line'].search([ + ('move_id', '=', self.bills_dp_id.id), + ('product_id', '=', product_dp.id), + ]) + + bills.message_post( + body=f"<div>" + f"<b>DP :</b><br>{move_line.price_unit}</div>", + subtype_id=self.env.ref("mail.mt_note").id + ) + + data_line_bills.append({ + 'move_id': bills.id, + 'product_id': product_dp.id, # product down payment + 'name': '[IT.121456] Down Payment', # product down payment + 'account_id': 401, # Uang Muka persediaan barang dagang + # 'price_unit': move_line.price_unit, + 'quantity': -1, + 'product_uom_id': 1, + 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in product_dp.taxes_id], + }) + + for line in self.order_line: + if line.product_id: + data_line_bills.append({ + 'move_id': bills.id, + 'product_id': line.product_id.id, + 'name': self.name + ": " + line.product_id.display_name, + 'account_id': 439, # Uang Muka persediaan barang dagang + 'quantity': line.product_qty, + # 'price_unit': line.price_subtotal, + 'product_uom_id': line.product_uom.id, + 'tax_ids': [(5, 0, 0)] + [(4, tax.id) for tax in line.taxes_id], + 'purchase_line_id': line.id, + 'purchase_order_id': line[0].order_id.id, + }) + + bills_line = self.env['account.move.line'].create(data_line_bills) + + self.bills_pelunasan_id = bills.id + + return { + 'name': _('Account Move'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', '=', bills.id)] + } + + + def create_bill_dp(self): if not self.env.user.is_accounting: raise UserError('Hanya Accounting yang bisa bikin bill dp') @@ -499,10 +585,29 @@ class PurchaseOrder(models.Model): picking.scheduled_date = self.date_planned picking.date_deadline = self.date_planned + def _check_qty_plafon_product(self): + for line in self.order_line: + if not line.product_id: + continue + # test = line.product_uom_qty + # test2 = line.product_id.plafon_qty + # test3 = test2 + line.product_uom_qty + if line.product_uom_qty > line.product_id.plafon_qty + line.product_uom_qty and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + raise UserError('Product '+line.product_id.name+' melebihi plafon, harus Approval MD') + + def check_different_vendor_so_po(self): + vendor_po = self.partner_id.id + for line in self.order_line: + if not line.so_line_id: + continue + if line.so_line_id.vendor_id.id != vendor_po and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): + raise UserError("Produk "+line.product_id.name+" memiliki vendor berbeda dengan SO (Vendor PO: "+str(self.partner_id.name)+", Vendor SO: "+str(line.so_line_id.vendor_id.name)+")") + def button_confirm(self): res = super(PurchaseOrder, self).button_confirm() current_time = datetime.now() self.check_ppn_mix() + self.check_different_vendor_so_po() # self.check_data_vendor() if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): @@ -511,7 +616,7 @@ class PurchaseOrder(models.Model): if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Beda Margin dengan Sales, harus approval Merchandise") if not self.from_apo: - if not self.sale_order_id and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: + if not self.matches_so and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader: raise UserError("Tidak ada link dengan SO, harus approval Merchandise") send_email = False @@ -551,7 +656,8 @@ class PurchaseOrder(models.Model): self.date_planned = delta_time self.date_deadline_ref_date_planned() self.unlink_purchasing_job_state() - + + self._check_qty_plafon_product() return res @@ -639,14 +745,63 @@ class PurchaseOrder(models.Model): template.send_mail(self.id, force_send=True) def po_approve(self): - if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): - raise UserError("Hanya Merchandiser yang bisa approve") + greater_than_plafon, message = self._get_msg_plafon_qty() + different_vendor_message = self.check_different_vendor_so() # Panggil fungsi check_different_vendor_so + if self.env.user.is_leader or self.env.user.has_group('indoteknik_custom.group_role_merchandiser'): raise UserError("Bisa langsung Confirm") - elif self.total_percent_margin == self.total_so_percent_margin and self.sale_order_id: + elif self.total_percent_margin == self.total_so_percent_margin and self.matches_so and not greater_than_plafon and not different_vendor_message: raise UserError("Bisa langsung Confirm") else: + reason = '' self.approval_status = 'pengajuan1' + if self.amount_untaxed >= 50000000: + reason = 'above 50jt, ' + if self.total_percent_margin < self.total_so_percent_margin: + reason += 'diff margin, ' + if not self.from_apo and not self.matches_so: + reason += 'not link with pj and reorder, ' + if not self.matches_so: + reason += 'not link with so, ' + # Check Plafon Qty and Get Message every Line Product + if greater_than_plafon: + reason += message + # Check for Different Vendor Message + if different_vendor_message: + reason += different_vendor_message + + # Post a highlighted message to lognote + self.message_post( + body=f"<div style='background-color: #fdf2e9; border: 1px solid #f5c6cb; padding: 10px;'>" + f"<b>Note (Pinned):</b><br>{reason}</div>", + subtype_id=self.env.ref("mail.mt_note").id + ) + + + def check_different_vendor_so(self): + vendor_po = self.partner_id.id + message = '' + for line in self.order_line: + if not line.so_line_id: + continue + if line.so_line_id.vendor_id.id != vendor_po: + product_code = line.product_id.display_name or 'Unknown' + message += (f"Produk {product_code} memiliki vendor berbeda dengan SO " + f"(Vendor PO: {self.partner_id.name}, Vendor SO: {line.so_line_id.vendor_id.name}), ") + return message if message else None + + def _get_msg_plafon_qty(self): + message = '' + greater_than_plafon = False + for line in self.order_line: + if not line.product_id: + continue + if line.product_uom_qty > line.product_id.plafon_qty: + message = (message + '\n'+line.product_id.default_code + ' melebihi plafon (' + + str(line.product_id.plafon_qty) + ') vs Qty PO ('+str(line.product_uom_qty)+')' + + ', ') + greater_than_plafon = True + return greater_than_plafon, message def re_calculate(self): if self.from_apo: |
