from odoo import fields, models, api, _ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT import logging _logger = logging.getLogger(__name__) class PurchaseOrderSalesMatch(models.Model): _name = 'purchase.order.sales.match' purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', index=True, required=True, ondelete='cascade') sale_id = fields.Many2one('sale.order', string='SO') sale_line_id = fields.Many2one('sale.order.line', string='SO Line') picking_id = fields.Many2one('stock.picking', string='Picking') move_id = fields.Many2one('stock.move', string='Move') partner_id = fields.Many2one('res.partner', string='Partner') partner_invoice_id = fields.Many2one('res.partner', string='Invoice Partner') salesperson_id = fields.Many2one('res.users', string='Sales') product_id = fields.Many2one('product.product', string='Product') qty_so = fields.Float(string='Qty SO') qty_po = fields.Float(string='Qty PO') margin_so = fields.Float(string='Margin SO') margin_item = fields.Float(string='Margin') delivery_amt = fields.Float(string='Delivery Amount', compute='_compute_delivery_amt') margin_deduct = fields.Float(string='After Deduct', compute='_compute_delivery_amt') purchase_price_so = fields.Float(string='Purchase Price Sale Order', related='sale_line_id.purchase_price') purchase_price_po = fields.Float('Purchase Price PO', compute='_compute_purchase_price_po') purchase_line_id = fields.Many2one('purchase.order.line', string='Purchase Line', compute='_compute_purchase_line_id') hold_outgoing_so = fields.Boolean(string='Hold Outgoing SO', related='sale_id.hold_outgoing') bu_pick = fields.Many2one('stock.picking', string='BU Pick', compute='compute_bu_pick') so_header_margin = fields.Float( related='sale_id.total_percent_margin', string='SO Header Margin %', readonly=True ) def compute_bu_pick(self): for rec in self: stock_move = self.env['stock.move'].search([ ('reference', 'ilike', 'BU/PICK'), ('state', 'in', ['confirmed','waiting','partially_available']), ('product_id', '=', rec.product_id.id), ('sale_line_id', '=', rec.sale_line_id.id), ]) if stock_move: rec.bu_pick = stock_move[0].picking_id.id else: rec.bu_pick = None def _compute_purchase_line_id(self): for line in self: line.purchase_line_id = self.env['purchase.order.line'].search([('order_id', '=', line.purchase_order_id.id), ('product_id', '=', line.product_id.id)]) def _compute_purchase_price_po(self): for line in self: purchase_price = self.env['purchase.order.line'].search([('order_id', '=', line.purchase_order_id.id), ('product_id', '=', line.product_id.id)]) line.purchase_price_po = purchase_price.price_unit def _compute_delivery_amt(self): for line in self: percent_margin = line.margin_item / line.purchase_order_id.total_margin_match \ if line.purchase_order_id.total_margin_match else 0 line.delivery_amt = line.purchase_order_id.delivery_amt * percent_margin line.margin_deduct = line.margin_item - line.delivery_amt @api.onchange('sale_id') def onchange_sale_id(self): self.salesperson_id = self.sale_id.user_id.id self.partner_id = self.sale_id.partner_id.id self.partner_invoice_id = self.sale_id.partner_invoice_id.id