Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions addons/sale_margin/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,11 @@ def _compute_purchase_price(self):
@api.depends('price_subtotal', 'product_uom_qty', 'purchase_price')
def _compute_margin(self):
for line in self:
line.margin = line.price_subtotal - (line.purchase_price * line.product_uom_qty)
line.margin_percent = line.price_subtotal and line.margin/line.price_subtotal
# Find alternative calculation when line is added to order from delivery
if line.qty_delivered and not line.product_uom_qty:
calculated_subtotal = line.price_unit * line.qty_delivered
line.margin = calculated_subtotal - (line.purchase_price * line.qty_delivered)
line.margin_percent = calculated_subtotal and line.margin / calculated_subtotal
else:
line.margin = line.price_subtotal - (line.purchase_price * line.product_uom_qty)
line.margin_percent = line.price_subtotal and line.margin / line.price_subtotal
16 changes: 10 additions & 6 deletions addons/sale_stock_margin/models/sale_order_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@ class SaleOrderLine(models.Model):

@api.depends('move_ids', 'move_ids.stock_valuation_layer_ids', 'move_ids.picking_id.state')
def _compute_purchase_price(self):
lines_without_moves = self.browse()
line_ids_to_pass = set()
for line in self:
product = line.product_id.with_company(line.company_id)
if not line.has_valued_move_ids():
lines_without_moves |= line
elif product and product.cost_method != 'standard':
purch_price = product._compute_average_price(0, line.product_uom_qty, line.move_ids)
line_ids_to_pass.add(line.id)
elif (
# don't overwrite any existing value unless non-standard cost method
(line.product_id and line.product_id.categ_id and line.product_id.categ_id.property_cost_method != 'standard') or
# if line added from delivery, allow recomputation
(not line.product_uom_qty and line.qty_delivered)
):
purch_price = product._compute_average_price(0, line.product_uom_qty or line.qty_to_invoice, line.move_ids)
if line.product_uom_id and line.product_uom_id != product.uom_id:
purch_price = product.uom_id._compute_price(purch_price, line.product_uom_id)
to_cur = line.currency_id or line.order_id.currency_id
line.purchase_price = line._convert_to_sol_currency(
purch_price,
product.cost_currency_id,
)
return super(SaleOrderLine, lines_without_moves)._compute_purchase_price()
return super(SaleOrderLine, self.browse(line_ids_to_pass))._compute_purchase_price()
34 changes: 34 additions & 0 deletions addons/sale_stock_margin/tests/test_sale_stock_margin.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,37 @@ def test_purchase_price_changes(self):

self.assertEqual(so.state, 'sent')
self.assertEqual(so.order_line[0].purchase_price, 15)
so.action_confirm()
self.assertEqual(so.order_line[0].purchase_price, 15)

def test_add_product_on_delivery_price_unit_on_sale(self):
""" Adding a product directly on a sale order's delivery should result in the new SOL
having its `purchase_price` and `margin` + `margin_percent` fields correctly calculated.
"""
products = [self._create_product() for _ in range(2)]
for product, cost, price in zip(products, [20, 10], [25, 20]):
product.categ_id.property_cost_method = 'standard'
product.write({
'standard_price': cost,
'list_price': price,
'invoice_policy': 'delivery',
})
sale_order = self._create_sale_order()
self._create_sale_order_line(sale_order, products[0], 10, products[0].list_price)
sale_order.action_confirm()
delivery = sale_order.picking_ids[0]
with Form(delivery) as delivery_form:
with delivery_form.move_ids_without_package.new() as move:
move.product_id = products[1]
move.product_uom_qty = 10
delivery.move_ids.quantity = 10
delivery.button_validate()
self.assertRecordValues(
sale_order.order_line.filtered(lambda sol: sol.product_id == products[1]),
[{
'price_unit': products[1].list_price,
'purchase_price': products[1].standard_price,
'margin': 100,
'margin_percent': 0.5,
}]
)