Skip to content

Commit

Permalink
[FIX] stock_customer_deposit: Allow to add more deposits of the same …
Browse files Browse the repository at this point in the history
…product
  • Loading branch information
Shide committed Nov 21, 2024
1 parent fee2358 commit 82d7e33
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 67 deletions.
100 changes: 56 additions & 44 deletions stock_customer_deposit/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools import float_compare


class SaleOrder(models.Model):
Expand All @@ -25,27 +26,25 @@ def _compute_customer_deposit_count(self):

def _action_confirm(self):
self._check_can_customer_deposit()
deposit_lines = self.order_line.filtered(
lambda line: line.deposit_available_qty > 0.0 and line.product_uom_qty > 0.0
)
if not deposit_lines:
return super()._action_confirm()
if deposit_lines.filtered(
lambda line: line.route_id == line.warehouse_id.customer_deposit_route_id
):
raise ValidationError(
_(
"You can't use customer deposit for products with the route"
" 'Customer Deposit'."
)
)
for order in self:
for order in self.filtered(lambda o: not o.customer_deposit):
deposit_lines = order.order_line.filtered(
lambda line: line.deposit_available_qty > 0.0
and line.product_uom_qty > 0.0
lambda line: float_compare(
line.deposit_available_qty,
0.0,
precision_rounding=line.product_id.uom_id.rounding,
)
> 0
and float_compare(
line.product_uom_qty,
0.0,
precision_rounding=line.product_id.uom_id.rounding,
)
> 0
)
# Normal order
if not deposit_lines:
continue
# Taking from deposit order
quants_by_product = self.env["stock.quant"].read_group(
domain=order._get_customer_deposit_domain(),
fields=["available_quantity"],
Expand All @@ -58,10 +57,17 @@ def _action_confirm(self):
for quant_by_product in quants_by_product
}
for product in deposit_lines.mapped("product_id"):
if product_deposit.get(product.id, 0.0) < sum(
deposit_lines.filtered(
lambda line: line.product_id.id == product.id
).mapped("product_uom_qty")
if (
float_compare(
product_deposit.get(product.id, 0.0),
sum(
deposit_lines.filtered(
lambda line: line.product_id.id == product.id
).mapped("product_uom_qty")
),
precision_rounding=product.uom_id.rounding,
)
< 0
):
raise ValidationError(
_(
Expand All @@ -71,32 +77,38 @@ def _action_confirm(self):
product=product.name,
)
)
return super(SaleOrder, self)._action_confirm()
return super()._action_confirm()

def _check_can_customer_deposit(self):
if self.filtered("customer_deposit").order_line.filtered(
lambda line: line.product_id.type == "product"
and line.route_id != line.warehouse_id.customer_deposit_route_id
):
raise ValidationError(
_(
"All lines coming from orders marked as 'Customer depot' must"
" have Customer deposit route."
)
)

if self.order_line.filtered(
lambda line: line.product_id.type == "product"
and line.warehouse_id.customer_deposit_route_id
and not line.order_id.customer_deposit
and line.route_id == line.warehouse_id.customer_deposit_route_id
):
raise ValidationError(
_(
"You cannot select Customer Deposit route in an order line if you"
" do not mark the order as a customer depot."
)
"""Check if the order is valid to perform a deposit or take from deposit"""
for order in self:
product_lines = order.order_line.filtered(
lambda line: line.product_id.type == "product"
)
if order.customer_deposit:
# Perform deposit
if product_lines.filtered(
lambda line: line.route_id
!= line.warehouse_id.customer_deposit_route_id
):
raise ValidationError(
_(
"All lines coming from orders marked as 'Customer depot' must"
" have Customer deposit route."
)
)
elif order.warehouse_id.customer_deposit_route_id:
# Take from deposit
if product_lines.filtered(
lambda line: line.route_id
== line.warehouse_id.customer_deposit_route_id
):
raise ValidationError(
_(
"You cannot select Customer Deposit route in an order line if you"
" do not mark the order as a customer depot."
)
)

def _get_customer_deposit_domain(self):
return [
Expand Down
1 change: 1 addition & 0 deletions stock_customer_deposit/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class SaleOrderLine(models.Model):
"product_id", "warehouse_id.use_customer_deposits", "order_id.customer_deposit"
)
def _compute_route_id(self):
"""Set route_id to customer deposit route if use_customer_deposits is True"""
for line in self:
line.route_id = (
line.warehouse_id.customer_deposit_route_id
Expand Down
60 changes: 38 additions & 22 deletions stock_customer_deposit/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@


from odoo import models
from odoo.tools import float_compare


class StockMove(models.Model):
Expand All @@ -11,32 +12,47 @@ class StockMove(models.Model):
def _action_assign(self, force_qty=False):
if self.env.context.get("owner", False):
return super(StockMove, self)._action_assign(force_qty=force_qty)
# moves from warehouse with customer deposits activate
moves_customer_deposits = self.filtered(
lambda move: move.warehouse_id.use_customer_deposits

# Warehouse not configured to use customer deposits
no_deposit_config_moves = self.filtered(
lambda move: not move.warehouse_id.use_customer_deposits
)
# moves with warehouse that have deactivated customer deposits should not do anything.
super(StockMove, self - moves_customer_deposits)._action_assign(
force_qty=force_qty
super(StockMove, no_deposit_config_moves)._action_assign(force_qty=force_qty)
# Warehouse configured to use customer deposits
deposit_config_moves = self - no_deposit_config_moves
# Move needs to create deposit
moves_push_deposit_route = deposit_config_moves.filtered(
lambda move: move.warehouse_id.customer_deposit_route_id in move.route_ids
)
# moves with warehouse that have activated customer deposits must assign owner
moves_owner = moves_customer_deposits.filtered(
lambda m: self.env["stock.quant"]._get_available_quantity(
m.product_id,
m.location_id,
owner_id=m.partner_id.commercial_partner_id or m.partner_id,
# Move needs to take from deposit or stock
moves_pull_from_stock = deposit_config_moves - moves_push_deposit_route
for move in moves_pull_from_stock:
# Check if move can take from deposit
move_owner_qty = move._get_available_quantity(
move.location_id,
lot_id=None,
package_id=None,
owner_id=move.partner_id.commercial_partner_id or move.partner_id,
strict=False,
allow_negative=False,
)
> 0.0
)
for move in moves_owner:
super(
StockMove,
move.with_context(
owner=move.partner_id.commercial_partner_id.id or move.partner_id.id
),
)._action_assign(force_qty=force_qty)
owner = False
if (
float_compare(
move_owner_qty,
move.product_uom_qty,
precision_rounding=move.product_uom.rounding,
)
>= 0
):
# Enough qty to take from deposit: Propagate assign with owner context
owner = move.partner_id.commercial_partner_id.id or move.partner_id.id
super(StockMove, move.with_context(owner=owner))._action_assign(
force_qty=force_qty
)

return super(
StockMove, (moves_customer_deposits - moves_owner).with_context(owner=False)
StockMove, moves_push_deposit_route.with_context(owner=False)
)._action_assign(force_qty=force_qty)

def _get_out_move_lines(self):
Expand Down
5 changes: 4 additions & 1 deletion stock_customer_deposit/models/stock_quant.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from odoo import api, models
from odoo.osv import expression
from odoo.tools import float_compare


class StockQuant(models.Model):
Expand Down Expand Up @@ -47,7 +48,9 @@ def _update_available_quantity(
owner_id=None,
in_date=None,
):
if quantity > 0 and self.env.context.get("owner", False):
if float_compare(
quantity, 0.0, precision_rounding=product_id.uom_id.rounding
) > 0 and self.env.context.get("owner", False):
owner_id = (
owner_id
or self.env["res.partner"].browse(self.env.context.get("owner"))
Expand Down
27 changes: 27 additions & 0 deletions stock_customer_deposit/tests/test_sale_customer_deposit.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def setUpClass(cls):
cls.productB: 110,
},
}
cls.result_test_second_deposit = {
False: {
cls.productA: 100,
cls.productB: 80,
},
cls.partner1: {
cls.productA: 200,
cls.productB: 220,
},
}

@users("user_customer_deposit")
def test_sale_customer_deposit(self):
Expand Down Expand Up @@ -107,6 +117,23 @@ def test_sale_customer_deposit(self):
product, self.warehouse.lot_stock_id, owner_id=partner
),
quantity,
"First deposit not added correctly",
)
# Add another order to deposit
so_2 = so.copy()
so_2.action_confirm()
so_2.picking_ids.action_confirm()
so_2.picking_ids.action_assign()
so_2.picking_ids.action_set_quantities_to_reservation()
so_2.picking_ids.button_validate()
for partner, products in self.result_test_second_deposit.items():
for product, quantity in products.items():
self.assertEqual(
self.env["stock.quant"]._get_available_quantity(
product, self.warehouse.lot_stock_id, owner_id=partner
),
quantity,
"Second deposit not added correctly",
)

@users("user_customer_deposit")
Expand Down

0 comments on commit 82d7e33

Please sign in to comment.