diff options
| -rw-r--r-- | addons/purchase/models/purchase.py | 35 | ||||
| -rw-r--r-- | addons/purchase/views/purchase_views.xml | 4 | ||||
| -rw-r--r-- | addons/purchase_mrp/models/purchase_mrp.py | 16 | ||||
| -rw-r--r-- | addons/purchase_stock/models/purchase.py | 37 | ||||
| -rw-r--r-- | addons/purchase_stock/models/stock.py | 12 |
5 files changed, 71 insertions, 33 deletions
diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 829c1e86684..c500f5c6cb4 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -427,7 +427,13 @@ class PurchaseOrderLine(models.Model): # Replace by invoiced Qty qty_invoiced = fields.Float(compute='_compute_qty_invoiced', string="Billed Qty", digits=dp.get_precision('Product Unit of Measure'), store=True) - qty_received = fields.Float(string="Received Qty", digits=dp.get_precision('Product Unit of Measure'), copy=False) + + qty_received_method = fields.Selection([('manual', 'Manual')], string="Received Qty Method", compute='_compute_qty_received_method', store=True, + help="According to product configuration, the recieved quantity can be automatically computed by mechanism :\n" + " - Manual: the quantity is set manually on the line\n" + " - Stock Moves: the quantity comes from confirmed pickings\n") + qty_received = fields.Float("Received Qty", compute='_compute_qty_received', inverse='_inverse_qty_received', compute_sudo=True, store=True, digits=dp.get_precision('Product Unit of Measure')) + qty_received_manual = fields.Float("Manual Received Qty", digits=dp.get_precision('Product Unit of Measure'), copy=False) partner_id = fields.Many2one('res.partner', related='order_id.partner_id', string='Partner', readonly=True, store=True) currency_id = fields.Many2one(related='order_id.currency_id', store=True, string='Currency', readonly=True) @@ -484,6 +490,33 @@ class PurchaseOrderLine(models.Model): qty -= inv_line.uom_id._compute_quantity(inv_line.quantity, line.product_uom) line.qty_invoiced = qty + @api.multi + @api.depends('product_id') + def _compute_qty_received_method(self): + for line in self: + if line.product_id.type in ['consu', 'service']: + line.qty_received_method = 'manual' + + @api.multi + @api.depends('qty_received_method', 'qty_received_manual') + def _compute_qty_received(self): + for line in self: + if line.qty_received_method == 'manual': + line.qty_received = line.qty_received_manual or 0.0 + + @api.multi + @api.onchange('qty_received') + def _inverse_qty_received(self): + """ When writing on qty_received, if the value should be modify manually (`qty_received_method` = 'manual' only), + then we put the value in `qty_received_manual`. Otherwise, `qty_received_manual` should be False since the + received qty is automatically compute by other mecanisms. + """ + for line in self: + if line.qty_received_method == 'manual': + line.qty_received_manual = line.qty_received + else: + line.qty_received_manual = 0.0 + @api.model def create(self, values): line = super(PurchaseOrderLine, self).create(values) diff --git a/addons/purchase/views/purchase_views.xml b/addons/purchase/views/purchase_views.xml index 5679d565c9c..6ec235e341a 100644 --- a/addons/purchase/views/purchase_views.xml +++ b/addons/purchase/views/purchase_views.xml @@ -192,7 +192,9 @@ <field name="account_analytic_id" context="{'default_partner_id':parent.partner_id}" groups="analytic.group_analytic_accounting"/> <field name="analytic_tag_ids" groups="analytic.group_analytic_tags" widget="many2many_tags" options="{'color_field': 'color'}"/> <field name="product_qty"/> - <field name="qty_received" attrs="{'column_invisible': [('parent.state', 'not in', ('purchase', 'done'))]}"/> + <field name="qty_received_manual" invisible="1"/> + <field name="qty_received_method" invisible="1"/> + <field name="qty_received" attrs="{'column_invisible': [('parent.state', 'not in', ('purchase', 'done'))], 'readonly': [('qty_received_method', '!=', 'manual')]}"/> <field name="qty_invoiced" attrs="{'column_invisible': [('parent.state', 'not in', ('purchase', 'done'))]}"/> <field name="product_uom" groups="uom.group_uom" attrs="{'readonly': [('state', 'in', ('purchase', 'done', 'cancel'))]}" force_save="1"/> <field name="price_unit"/> diff --git a/addons/purchase_mrp/models/purchase_mrp.py b/addons/purchase_mrp/models/purchase_mrp.py index c554d64e152..176c86cb358 100644 --- a/addons/purchase_mrp/models/purchase_mrp.py +++ b/addons/purchase_mrp/models/purchase_mrp.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models +from odoo import api, fields, models from odoo.tools import float_compare @@ -14,12 +14,14 @@ class MrpProduction(models.Model): class PurchaseOrderLine(models.Model): _inherit = 'purchase.order.line' - def _update_received_qty(self): - super(PurchaseOrderLine, self)._update_received_qty() - for line in self.filtered(lambda x: x.move_ids and x.product_id.id not in x.move_ids.mapped('product_id').ids): - bom = self.env['mrp.bom']._bom_find(product=line.product_id, company_id=line.company_id.id) - if bom and bom.type == 'phantom': - line.qty_received = line._get_bom_delivered(bom=bom) + @api.multi + def _compute_qty_received(self): + super(PurchaseOrderLine, self)._compute_qty_received() + for line in self: + if line.qty_received_method == 'stock_moves' and line.move_ids and line.product_id.id not in line.move_ids.mapped('product_id').ids: + bom = self.env['mrp.bom']._bom_find(product=line.product_id, company_id=line.company_id.id) + if bom and bom.type == 'phantom': + line.qty_received = line._get_bom_delivered(bom=bom) def _get_bom_delivered(self, bom=False): self.ensure_one() diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py index 5d923719ebb..3cc797255cd 100644 --- a/addons/purchase_stock/models/purchase.py +++ b/addons/purchase_stock/models/purchase.py @@ -221,10 +221,35 @@ class PurchaseOrder(models.Model): class PurchaseOrderLine(models.Model): _inherit = 'purchase.order.line' + qty_received_method = fields.Selection(selection_add=[('stock_moves', 'Stock Moves')]) + move_ids = fields.One2many('stock.move', 'purchase_line_id', string='Reservation', readonly=True, ondelete='set null', copy=False) orderpoint_id = fields.Many2one('stock.warehouse.orderpoint', 'Orderpoint') move_dest_ids = fields.One2many('stock.move', 'created_purchase_line_id', 'Downstream Moves') + @api.multi + def _compute_qty_received_method(self): + super(PurchaseOrderLine, self)._compute_qty_received_method() + for line in self: + if line.product_id.type in ['consu', 'product']: + line.qty_received_method = 'stock_moves' + + @api.multi + @api.depends('move_ids.state', 'move_ids.product_uom_qty', 'move_ids.product_uom') + def _compute_qty_received(self): + super(PurchaseOrderLine, self)._compute_qty_received() + for line in self: + if line.qty_received_method == 'stock_moves': + total = 0.0 + for move in line.move_ids: + if move.state == 'done': + if move.location_dest_id.usage == "supplier": + if move.to_refund: + total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) + else: + total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) + line.qty_received = total + @api.model def create(self, values): line = super(PurchaseOrderLine, self).create(values) @@ -354,18 +379,6 @@ class PurchaseOrderLine(models.Model): done += moves.create(val) return done - def _update_received_qty(self): - for line in self: - total = 0.0 - for move in line.move_ids: - if move.state == 'done': - if move.location_dest_id.usage == "supplier": - if move.to_refund: - total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) - else: - total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) - line.qty_received = total - def _merge_in_existing_line(self, product_id, product_qty, product_uom, location_id, name, origin, values): """ This function purpose is to be override with the purpose to forbide _run_buy method to merge a new po line in an existing one. diff --git a/addons/purchase_stock/models/stock.py b/addons/purchase_stock/models/stock.py index 385899aa194..440177955d2 100644 --- a/addons/purchase_stock/models/stock.py +++ b/addons/purchase_stock/models/stock.py @@ -82,18 +82,6 @@ class StockMove(models.Model): super(StockMove, self)._clean_merged() self.write({'created_purchase_line_id': False}) - def _action_done(self, cancel_backorder=False): - res = super(StockMove, self)._action_done(cancel_backorder=cancel_backorder) - self.mapped('purchase_line_id').sudo()._update_received_qty() - return res - - def write(self, vals): - res = super(StockMove, self).write(vals) - if 'product_uom_qty' in vals: - self.filtered(lambda m: m.state == 'done' and m.purchase_line_id).mapped( - 'purchase_line_id').sudo()._update_received_qty() - return res - def _get_upstream_documents_and_responsibles(self, visited): if self.created_purchase_line_id and self.created_purchase_line_id.state not in ('done', 'cancel'): return [(self.created_purchase_line_id.order_id, self.created_purchase_line_id.order_id.user_id, visited)] |
