Skip to content

Commit

Permalink
Merge PR #215 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by Shide
  • Loading branch information
OCA-git-bot committed Jun 24, 2024
2 parents 6d9434f + 40f3658 commit 6787222
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 20 deletions.
2 changes: 1 addition & 1 deletion sale_margin_delivered/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Sale Margin Delivered",
"version": "16.0.1.0.5",
"version": "16.0.2.0.0",
"author": "Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/margin-analysis",
"category": "Sales",
Expand Down
15 changes: 15 additions & 0 deletions sale_margin_delivered/migrations/16.0.2.0.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import logging

_logger = logging.getLogger(__name__)


def migrate(cr, version=None):
"""Store margin delivered precentage as a fraction of 1"""
cr.execute(
"""
UPDATE sale_order_line
SET margin_delivered_percent = margin_delivered_percent / 100
WHERE margin_delivered_percent > 0
"""
)
_logger.info("Updated %d records", cr.rowcount)
20 changes: 13 additions & 7 deletions sale_margin_delivered/models/sale_margin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SaleOrderLine(models.Model):
help="Margin percent between the Unit Price with discounts and "
"Delivered Unit Cost.\n\n"
"Formula: ((Unit Price with Discounts - Average Unit Cost of "
"delivered products) / Unit Price with Discounts) * 100.0",
"delivered products) / Unit Price with Discounts)",
)
purchase_price_delivery = fields.Float(
compute="_compute_margin_delivered",
Expand Down Expand Up @@ -72,6 +72,14 @@ def _compute_margin_delivered(self):
self.margin_delivered_percent = 0.0
self.purchase_price_delivery = 0.0
for line in self.filtered("qty_delivered"):
# we need to compute the price reduce to avoid rounding issues
# the one stored in the line is rounded to the product price precision
price_reduce_taxexcl = (
line.price_subtotal / line.product_uom_qty
if line.product_uom_qty
else 0.0
)

if line.product_id.type != "product":
currency = line.order_id.pricelist_id.currency_id
price = line.purchase_price
Expand All @@ -91,13 +99,11 @@ def _compute_margin_delivered(self):
)
# Inverse qty_delivered because outgoing quantities are negative
line.margin_delivered = -qty_delivered * (
line.price_reduce - line.purchase_price_delivery
price_reduce_taxexcl - line.purchase_price_delivery
)
# compute percent margin based on delivered quantities or ordered
# quantities
if line.price_reduce:
if price_reduce_taxexcl:
line.margin_delivered_percent = (
(line.price_reduce - line.purchase_price_delivery)
/ line.price_reduce
* 100.0
)
price_reduce_taxexcl - line.purchase_price_delivery
) / price_reduce_taxexcl
11 changes: 7 additions & 4 deletions sale_margin_delivered/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

/*
:Author: David Goodger ([email protected])
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -300,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -452,7 +453,9 @@ <h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
Expand Down
47 changes: 41 additions & 6 deletions sale_margin_delivered/tests/test_sale_margin_delivered.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_sale_margin_delivered(self):
picking._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 30.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_delivered_excess(self):
Expand All @@ -104,7 +104,7 @@ def test_sale_margin_delivered_excess(self):
picking._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 120.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_zero(self):
Expand Down Expand Up @@ -142,7 +142,7 @@ def test_sale_margin_delivered_return_to_refund(self):
picking_return._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 30.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_delivered_return_to_refund_excess(self):
Expand All @@ -155,7 +155,7 @@ def test_sale_margin_delivered_return_to_refund_excess(self):
picking_return._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 90.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_delivered_return_no_refund(self):
Expand All @@ -168,7 +168,7 @@ def test_sale_margin_delivered_return_no_refund(self):
picking_return._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 60.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_delivered_return_no_refund_excess(self):
Expand All @@ -181,5 +181,40 @@ def test_sale_margin_delivered_return_no_refund_excess(self):
picking_return._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 120.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_delivered_precision(self):
self.product.standard_price = 10.30
self.product.list_price = 20.17
sale_order = self._new_sale_order()
sale_order.order_line[:1].discount = 17.0
sale_order.action_confirm()
picking = sale_order.picking_ids
picking.action_assign()
picking.move_line_ids.qty_done = 6.0
picking._action_done()
order_line = sale_order.order_line[:1]
# price_subtotal is rounded
self.assertEqual(order_line.price_subtotal, 100.45)
# the unit reduce price will be computed as 100.45 / 6 = 16.741666666666667
# it should not be rounded to 16.74
# margin_delivered: round(6 * ((100.45 /6) - 10.30)) != round(6 * (16.74 - 10.30))
self.assertEqual(order_line.margin_delivered, 38.65)
self.assertAlmostEqual(order_line.margin_delivered_percent, 0.38476854156296)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

def test_sale_margin_no_cost(self):
self.product.standard_price = 0.0
self.product.list_price = 20
sale_order = self._new_sale_order()
sale_order.action_confirm()
picking = sale_order.picking_ids
picking.action_assign()
picking.move_line_ids.qty_done = 6.0
picking._action_done()
order_line = sale_order.order_line[:1]
# price_subtotal is rounded
self.assertEqual(order_line.margin_delivered, 120)
self.assertAlmostEqual(order_line.margin_delivered_percent, 1)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)
4 changes: 3 additions & 1 deletion sale_margin_delivered/views/sale_margin_delivered_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale_margin.sale_margin_sale_order_line_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='margin']" position="after">
<xpath expr="//field[@name='margin_percent']" position="after">
<field
name="purchase_price_delivery"
string="Cost Price dlvd."
Expand All @@ -16,6 +16,8 @@
name="margin_delivered_percent"
string="Margin dlvd. (%)"
optional="hide"
attrs="{'invisible': [('price_subtotal', '=', 0)]}"
widget="percentage"
/>
<field name="margin_delivered" string="Margin dlvd." optional="hide" />
</xpath>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ def test_sale_margin_delivered_dropship(self):
picking_return._action_done()
order_line = sale_order.order_line[:1]
self.assertEqual(order_line.margin_delivered, 30.0)
self.assertEqual(order_line.margin_delivered_percent, 50.0)
self.assertEqual(order_line.margin_delivered_percent, 0.5)
self.assertEqual(order_line.purchase_price_delivery, order_line.purchase_price)

0 comments on commit 6787222

Please sign in to comment.