summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/purchase/models/purchase.py35
-rw-r--r--addons/purchase/views/purchase_views.xml4
-rw-r--r--addons/purchase_mrp/models/purchase_mrp.py16
-rw-r--r--addons/purchase_stock/models/purchase.py37
-rw-r--r--addons/purchase_stock/models/stock.py12
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)]