from odoo import models, api, fields from odoo.exceptions import AccessError, UserError, ValidationError from datetime import timedelta, date import logging _logger = logging.getLogger(__name__) class VendorApproval(models.Model): _name = "vendor.approval" _description = "Vendor Approval" _inherit = ['mail.thread'] _rec_name = 'number' number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True) partner_id = fields.Many2one('res.partner', string="Customer", readonly=True) order_line_id = fields.Many2one('sale.order.line', string="SO Line", readonly=True) order_id = fields.Many2one('sale.order', string="SO", readonly=True) state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Reject')], string='State', tracking=True) create_date_so = fields.Datetime(string='Create Date SO', readonly=True) product_id = fields.Many2one('product.product', string='Product') product_uom_qty = fields.Float(string='Quantity') vendor_id = fields.Many2one('res.partner', string='Vendor') vendor_md_id = fields.Many2one('res.partner', string='Vendor MD') sales_price = fields.Float(string='Sales Price') margin_before = fields.Float(string='Margin Before') margin_after = fields.Float(string='Margin After') purchase_price = fields.Float(string='Purchase Price') purchase_price_md= fields.Float(string='Purchase Price MD') purchase_tax_id = fields.Many2one('account.tax', string='Purchase Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) sales_tax_id = fields.Many2one('account.tax', string='Sales Tax', domain=['|', ('active', '=', False), ('active', '=', True)]) percent_margin_difference = fields.Float(string='Percent Margin Difference') @api.model def create(self, vals): vals['number'] = self.env['ir.sequence'].next_by_code('vendor.approval') or '0' result = super(VendorApproval, self).create(vals) return result def check_state_so(self): for rec in self: if rec.order_id.state != 'draft': raise UserError(f"SO {rec.order_id.name} sudah tidak bisa diubah") def action_approve(self): for rec in self: self.check_state_so() if not self.env.user.has_group('indoteknik_custom.group_role_purchasing'): raise UserError('Hanya Merchandiser yang bisa approve') # Set state menjadi 'done' rec.state = 'done' rec.order_id.vendor_approval = True message = f"Vendor Approval approved by {self.env.user.name}" rec.order_id.message_post(body=message) # Cek semua vendor.approval dengan order_id yang sama related_approvals = self.env['vendor.approval'].search([('order_id', '=', rec.order_id.id)]) if all(approval.state != 'draft' for approval in related_approvals): # Jalankan action_confirm hanya jika semua state bukan draft if not rec.order_id.due_id and rec.order_id.state == 'draft': rec.order_id.action_confirm() def action_reject(self): for rec in self: self.check_state_so() if not self.env.user.has_group('indoteknik_custom.group_role_purchasing'): raise UserError('Hanya Procurement yang bisa cancel') rec.state = 'cancel' rec.order_line_id.vendor_id = rec.vendor_md_id.id rec.order_line_id.purchase_price = rec.purchase_price_md message = "Vendor Approval rejected by %s" % (self.env.user.name) self.order_id.message_post(body=message) related_approvals = self.env['vendor.approval'].search([('order_id', '=', rec.order_id.id)]) if all(approval.state != 'draft' for approval in related_approvals): # Jalankan action_confirm hanya jika semua state bukan draft if not rec.order_id.due_id and rec.order_id.state == 'draft': rec.order_id.action_confirm() def unlink(self): res = super(VendorApproval, self).unlink() if not self._name == 'vendor.approval': raise UserError('Vendor Approval tidak bisa didelete') return res def open_form_multi_approve(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_va_multi_approve') action['context'] = { 'va_ids': [x.id for x in self] } return action def open_form_multi_reject(self): action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_va_multi_reject') action['context'] = { 'va_ids': [x.id for x in self] } return action