Skip to content

Commit

Permalink
Merge commit 'refs/pull/1145/head' of https://github.com/oca/stock-lo…
Browse files Browse the repository at this point in the history
…gistics-workflow into 13.0-1904
  • Loading branch information
docker-odoo committed Mar 29, 2023
2 parents 7429acf + 972ff71 commit de23a62
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 21 deletions.
1 change: 1 addition & 0 deletions stock_split_picking/models/__init__.py
Expand Up @@ -2,3 +2,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import stock_picking
from . import stock_move_line
106 changes: 106 additions & 0 deletions stock_split_picking/models/stock_move_line.py
@@ -0,0 +1,106 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, models
from odoo.exceptions import UserError
from odoo.tools.float_utils import float_compare, float_is_zero, float_round


class StockMoveLine(models.Model):

_inherit = "stock.move.line"

def _prepare_move_split_vals(self, qty, move_id):
""" Values to be set in the new move line.
We set the qty_done so the new line keeps the done quantities.
"""
vals = {
"product_uom_qty": qty,
"qty_done": self.qty_done,
"move_id": move_id,
}
if self.env.context.get("force_split_uom_id"):
vals["product_uom_id"] = self.env.context["force_split_uom_id"]
return vals

def _get_original_move_vals(self, qty):
decimal_precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
new_product_qty = self.product_id.uom_id._compute_quantity(
self.product_qty - qty, self.product_uom_id, round=False
)
new_product_qty = float_round(
new_product_qty, precision_digits=decimal_precision
)
return {
"product_uom_qty": new_product_qty,
"qty_done": 0.0,
}

def _split(self, qty, move_id):
""" Splits a stock move line with a defined qty and move to a new stock move
:param qty: float. quantity to split (given in product UoM)
:returns: id of the backorder move line created """
self.ensure_one()
self = self.with_prefetch()
# This makes the ORM only look for one record and not 300 at a time,
# which improves performance
if self.state in ("done", "cancel"):
raise UserError(
_("You cannot split a stock move line that has been set to 'Done'.")
)
elif self.state == "draft":
# we restrict the split of a draft line because if not confirmed yet.
raise UserError(
_("You cannot split a draft line. It needs to be confirmed first.")
)
if (
float_is_zero(qty, precision_rounding=self.product_id.uom_id.rounding)
or self.product_qty <= qty
):
self.move_id = move_id
return self.id

decimal_precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)

# `qty` passed as argument is the quantity to backorder and is always expressed in the
# quants UOM.
uom_qty = self.product_id.uom_id._compute_quantity(
qty, self.product_uom_id, rounding_method="HALF-UP"
)
# TODO: usamos precision_digits porque le copiamos a odoo con stock move,
# pero quizás debería ser: precision_rounding=self.product_id.uom_id.rounding
if (
float_compare(
qty,
self.product_uom_id._compute_quantity(
uom_qty, self.product_id.uom_id, rounding_method="HALF-UP"
),
precision_digits=decimal_precision,
)
== 0
):
defaults = self._prepare_move_split_vals(uom_qty, move_id)
else:
defaults = self.with_context(
force_split_uom_id=self.product_id.uom_id.id
)._prepare_move_split_vals(qty, move_id)

ml = self.with_context(rounding_method="HALF-UP").copy(defaults)
self.write(self._get_original_move_vals(qty))

# We need to update quants reservations because it is not
# properly updated when copy a line
self.env["stock.quant"]._update_reserved_quantity(
ml.product_id,
ml.location_id,
ml.product_qty,
lot_id=ml.lot_id,
package_id=ml.package_id,
owner_id=ml.owner_id,
strict=True,
)
return ml.id
47 changes: 27 additions & 20 deletions stock_split_picking/models/stock_picking.py
Expand Up @@ -4,15 +4,14 @@

from odoo import _, models
from odoo.exceptions import UserError
from odoo.tools.float_utils import float_compare


class StockPicking(models.Model):
"""Adds picking split without done state."""

_inherit = "stock.picking"

def split_process(self):
def split_process(self, keep_lines=False):
"""Use to trigger the wizard from button with correct context"""
for picking in self:

Expand All @@ -29,37 +28,45 @@ def split_process(self):

# Split moves considering the qty_done on moves
new_moves = self.env["stock.move"]
new_move_lines = self.env["stock.move.line"]
for move in picking.move_lines:
rounding = move.product_uom.rounding
qty_done = move.quantity_done
qty_initial = move.product_uom_qty
qty_diff_compare = float_compare(
qty_done, qty_initial, precision_rounding=rounding
)
if qty_diff_compare < 0:
qty_split = qty_initial - qty_done
if qty_done:
qty_uom_split = move.product_uom._compute_quantity(
qty_split, move.product_id.uom_id, rounding_method="HALF-UP"
qty_done, move.product_id.uom_id, rounding_method="HALF-UP"
)
new_move_id = move._split(qty_uom_split)
for move_line in move.move_line_ids:
if move_line.product_qty and move_line.qty_done:
# To avoid an error
# when picking is partially available
try:
move_line.write({"product_uom_qty": move_line.qty_done})
except UserError:
pass
if keep_lines:
new_move_line_id = move_line._split(
move_line.qty_done, new_move_id
)
new_move_lines |= self.env["stock.move.line"].browse(
new_move_line_id
)
else:
# To avoid an error
# when picking is partially available
try:
move_line.write(
{"product_uom_qty": move_line.qty_done}
)
except UserError:
pass

new_moves |= self.env["stock.move"].browse(new_move_id)

# If we have new moves to move, create the backorder picking
if new_moves:
backorder_picking = picking._create_split_backorder()
new_moves.write({"picking_id": backorder_picking.id})
new_moves.mapped("move_line_ids").write(
{"picking_id": backorder_picking.id}
)
new_moves._action_assign()
if new_move_lines:
new_move_lines.write({"picking_id": backorder_picking.id})
new_moves._recompute_state()
else:
new_moves._action_assign()
return backorder_picking

def _create_split_backorder(self, default=None):
"""Copy current picking with defaults passed, post message about
Expand Down
7 changes: 6 additions & 1 deletion stock_split_picking/wizards/stock_split_picking.py
Expand Up @@ -12,7 +12,8 @@ class StockSplitPicking(models.TransientModel):
[
("done", "Done quantities"),
("move", "One picking per move"),
("selection", "Select move lines to split off"),
("selection", "Select stock move to split off"),
("lines_done", "Done quantities keeping move lines"),
],
required=True,
default="done",
Expand All @@ -32,6 +33,10 @@ def action_apply(self):
def _apply_done(self):
return self.mapped("picking_ids").split_process()

def _apply_lines_done(self):
"""Move to a new picking the qty done keeping the stock move lines"""
return self.mapped("picking_ids").split_process(keep_lines=True)

def _apply_move(self):
"""Create new pickings for every move line, keep first
move line in original picking
Expand Down

0 comments on commit de23a62

Please sign in to comment.