[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 <pimodoo@users.noreply.github.com>
This commit is contained in:
Pierre Masereel
2020-12-04 08:01:36 +00:00
parent 5705814e73
commit 1fed54f885
4 changed files with 66 additions and 45 deletions
+56 -42
View File
@@ -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
@@ -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 = [];
+8 -1
View File
@@ -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;
@@ -6,7 +6,7 @@
<span class="product-name">
<t t-esc="props.line.get_full_product_name()"/>
<span> </span>
<t t-if="props.line.get_product().tracking!=='none'">
<t t-if="props.line.get_product().tracking!=='none' &amp;&amp; (env.pos.picking_type.use_create_lots || env.pos.picking_type.use_existing_lots)">
<t t-if="props.line.has_valid_product_lot()">
<i t-on-click.stop="lotIconClicked"
class="oe_link_icon fa fa-list oe_icon line-lot-icon oe_green"