From 1fed54f8858519ee50effd23b50634a72d31a063 Mon Sep 17 00:00:00 2001 From: Pierre Masereel Date: Thu, 26 Nov 2020 14:52:03 +0000 Subject: [PATCH] [FIX] point_of_sale: handle picking type without lot usage When you are configuring the picking type used in the point of sale to not use existing lots and not create lots, the POS still ask you to encode a lot for product tracked, and the picking created don't use existing lots in stock because no reservation is made when a picking is valaidated from point of sale. As we want to reserve only in this specific case, we are now checking the options on the picking type to reserve or not product tracked. We are also not asking anymore for lot or serial number if picking type is configured that way. OPW-2377008 closes odoo/odoo#62857 X-original-commit: f9dd1d88d0d24914028464cc12b69ff0878346f8 Signed-off-by: pimodoo --- addons/point_of_sale/models/stock_picking.py | 98 +++++++++++-------- .../js/Screens/ProductScreen/ProductScreen.js | 2 +- addons/point_of_sale/static/src/js/models.js | 9 +- .../xml/Screens/ProductScreen/Orderline.xml | 2 +- 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/addons/point_of_sale/models/stock_picking.py b/addons/point_of_sale/models/stock_picking.py index 6efc5b35815..70a7a866b18 100644 --- a/addons/point_of_sale/models/stock_picking.py +++ b/addons/point_of_sale/models/stock_picking.py @@ -3,7 +3,7 @@ from odoo import api,fields, models from odoo.exceptions import UserError, ValidationError -from odoo.tools import float_is_zero +from odoo.tools import float_is_zero, float_compare from itertools import groupby @@ -94,49 +94,63 @@ class StockPicking(models.Model): ) confirmed_moves = current_move._action_confirm() for move in confirmed_moves: - if first_line.product_id == move.product_id and first_line.product_id.tracking != 'none' and (self.picking_type_id.use_existing_lots or self.picking_type_id.use_create_lots): - for line in order_lines: - sum_of_lots = 0 - for lot in line.pack_lot_ids.filtered(lambda l: l.lot_name): - if line.product_id.tracking == 'serial': - qty = 1 - else: - qty = abs(line.qty) - ml_vals = move._prepare_move_line_vals() - ml_vals.update({'qty_done':qty}) - if self.picking_type_id.use_existing_lots: - existing_lot = self.env['stock.production.lot'].search([ - ('company_id', '=', self.company_id.id), - ('product_id', '=', line.product_id.id), - ('name', '=', lot.lot_name) - ]) - if not existing_lot and self.picking_type_id.use_create_lots: - existing_lot = self.env['stock.production.lot'].create({ - 'company_id': self.company_id.id, - 'product_id': line.product_id.id, - 'name': lot.lot_name, - }) - ml_vals.update({ - 'lot_id': existing_lot.id, - }) - else: - ml_vals.update({ - 'lot_name': lot.lot_name, - }) - self.env['stock.move.line'].create(ml_vals) - sum_of_lots += qty - if abs(line.qty) != sum_of_lots: - difference_qty = abs(line.qty) - sum_of_lots - ml_vals = current_move._prepare_move_line_vals() - if line.product_id.tracking == 'serial': - ml_vals.update({'qty_done': 1}) - for i in range(int(difference_qty)): + if first_line.product_id == move.product_id: + if first_line.product_id.tracking != 'none': + if self.picking_type_id.use_existing_lots or self.picking_type_id.use_create_lots: + for line in order_lines: + sum_of_lots = 0 + for lot in line.pack_lot_ids.filtered(lambda l: l.lot_name): + if line.product_id.tracking == 'serial': + qty = 1 + else: + qty = abs(line.qty) + ml_vals = move._prepare_move_line_vals() + ml_vals.update({'qty_done':qty}) + if self.picking_type_id.use_existing_lots: + existing_lot = self.env['stock.production.lot'].search([ + ('company_id', '=', self.company_id.id), + ('product_id', '=', line.product_id.id), + ('name', '=', lot.lot_name) + ]) + if not existing_lot and self.picking_type_id.use_create_lots: + existing_lot = self.env['stock.production.lot'].create({ + 'company_id': self.company_id.id, + 'product_id': line.product_id.id, + 'name': lot.lot_name, + }) + ml_vals.update({ + 'lot_id': existing_lot.id, + }) + else: + ml_vals.update({ + 'lot_name': lot.lot_name, + }) self.env['stock.move.line'].create(ml_vals) - else: - ml_vals.update({'qty_done': difference_qty}) + sum_of_lots += qty + if abs(line.qty) != sum_of_lots: + difference_qty = abs(line.qty) - sum_of_lots + ml_vals = current_move._prepare_move_line_vals() + if line.product_id.tracking == 'serial': + ml_vals.update({'qty_done': 1}) + for i in range(int(difference_qty)): + self.env['stock.move.line'].create(ml_vals) + else: + ml_vals.update({'qty_done': difference_qty}) + self.env['stock.move.line'].create(ml_vals) + else: + move._action_assign() + sum_of_lots = 0 + for move_line in move.move_line_ids: + move_line.qty_done = move_line.product_uom_qty + sum_of_lots += move_line.product_uom_qty + if float_compare(move.product_uom_qty, move.quantity_done, precision_rounding=move.product_uom.rounding) > 0: + remaining_qty = move.product_uom_qty - move.quantity_done + ml_vals = move._prepare_move_line_vals() + ml_vals.update({'qty_done':remaining_qty}) self.env['stock.move.line'].create(ml_vals) - else: - move.quantity_done = move.product_uom_qty + + else: + move.quantity_done = move.product_uom_qty def _send_confirmation_email(self): # Avoid sending Mail/SMS for POS deliveries diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js index 1bd9f73373b..3d4033ac6d9 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js @@ -84,7 +84,7 @@ odoo.define('point_of_sale.ProductScreen', function(require) { } // Gather lot information if required. - if (['serial', 'lot'].includes(product.tracking)) { + if (['serial', 'lot'].includes(product.tracking) && (this.env.pos.picking_type.use_create_lots || this.env.pos.picking_type.use_existing_lots)) { const isAllowOnlyOneLot = product.isAllowOnlyOneLot(); if (isAllowOnlyOneLot) { packLotLinesToEdit = []; diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 74dc933ffb2..809299f7a12 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -311,6 +311,13 @@ exports.PosModel = Backbone.Model.extend({ self.pos_session.sequence_number = Math.max(self.pos_session.sequence_number, orders[i].data.sequence_number+1); } }, + },{ + model: 'stock.picking.type', + fields: ['use_create_lots', 'use_existing_lots'], + domain: function(self){ return [['id', '=', self.config.picking_type_id[0]]]; }, + loaded: function(self, picking_type) { + self.picking_type = picking_type[0]; + }, },{ model: 'res.users', fields: ['name','company_id', 'id', 'groups_id', 'lang'], @@ -1847,7 +1854,7 @@ exports.Orderline = Backbone.Model.extend({ }else if(!utils.float_is_zero(price - order_line_price - orderline.get_price_extra(), this.pos.currency.decimals)){ return false; - }else if(this.product.tracking == 'lot') { + }else if(this.product.tracking == 'lot' && (this.pos.picking_type.use_create_lots || this.pos.picking_type.use_existing_lots)) { return false; }else if (this.description !== orderline.description) { return false; diff --git a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml index d0464f0e6d8..92c85515de7 100644 --- a/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml +++ b/addons/point_of_sale/static/src/xml/Screens/ProductScreen/Orderline.xml @@ -6,7 +6,7 @@ - +