Skip to content

Commit

Permalink
[REF+IMP] stock_picking_invoicing: Get Price Unit method to use in In…
Browse files Browse the repository at this point in the history
…voice consider the value of Product Pricelist or the Seller Price, changed Demo Data for tests.
  • Loading branch information
mbcosta committed Aug 24, 2023
1 parent 942100d commit 7a7600c
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 10 deletions.
2 changes: 1 addition & 1 deletion stock_picking_invoicing/demo/stock_picking_demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@
<!-- Supplier -->
<!-- Stocking Picking - To be Invoiced - State Assigned-->
<record id="stock_picking_invoicing_7" model="stock.picking">
<field name="partner_id" ref="base.res_partner_12" />
<field name="partner_id" ref="base.res_partner_4" />
<field name="picking_type_id" ref="stock.picking_type_in" />
<field name="invoice_state">2binvoiced</field>
<field name="origin">stock_picking_invoicing demo</field>
Expand Down
110 changes: 102 additions & 8 deletions stock_picking_invoicing/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import fields, models
from odoo.tools.float_utils import float_round


class StockMove(models.Model):
Expand All @@ -19,22 +20,115 @@ def _get_price_unit_invoice(self, inv_type, partner, qty=1):
:param qty: float
:return: float
"""

if inv_type in ("in_invoice", "in_refund"):
price_unit = min(self.mapped("price_unit"))
else:
price_unit = max(self.mapped("price_unit"))

if price_unit > 0.0:
# Value informed by user should has preferency
return price_unit

product = self.mapped("product_id")
product.ensure_one()
sum(self.mapped("product_uom_qty"))
product_uom = self.mapped("product_uom")
company = fields.first(self).picking_id.company_id
# Only in the cases the stock.move has linked to Sale or
# Purchase Order it's possible use different Currencys
# TODO: Should this module make possible by include field
# currency_id in Stock.picking?
currency = company.currency_id
pickings = self.mapped("picking_id")
date_done = min(pickings.mapped("date_done"))

if inv_type in ("in_invoice", "in_refund"):
result = product.standard_price

seller = product._select_seller(
partner_id=partner, quantity=qty, date=date_done
)
if not seller:
po_line_uom = self.mapped("product_uom") or product.uom_po_id
price_unit = self.env["account.tax"]._fix_tax_included_price_company(
product.uom_id._compute_price(product.standard_price, po_line_uom),
product.supplier_taxes_id,
# TODO: Should inform taxes_ids in stock.move?
product.supplier_taxes_id,
fields.first(self).company_id,
)
price_unit = product.currency_id._convert(
price_unit, currency, company, date_done, False
)
result = float_round(
price_unit,
precision_digits=max(
currency.decimal_places,
self.env["decimal.precision"].precision_get("Product Price"),
),
)
else:
price_unit = self.env["account.tax"]._fix_tax_included_price_company(
seller.price,
product.supplier_taxes_id,
# TODO: Should inform taxes_ids in stock.move?
product.supplier_taxes_id,
fields.first(self).company_id,
)
price_unit = seller.currency_id._convert(
price_unit, currency, company, date_done, False
)
price_unit = float_round(
price_unit,
precision_digits=max(
currency.decimal_places,
self.env["decimal.precision"].precision_get("Product Price"),
),
)
result = seller.product_uom._compute_price(price_unit, product_uom)

else:
# If partner given, search price in its sale pricelist
fiscal_position = (
self.env["account.fiscal.position"]
.with_company(company)
._get_fiscal_position(partner)
)

if partner and partner.property_product_pricelist:
product = product.with_context(
partner=partner.id,
quantity=qty,
pricelist=partner.property_product_pricelist.id,
uom=fields.first(self).product_uom.id,
price_unit = None
pricelist_rule_id = (
partner.property_product_pricelist._get_product_rule(
product,
qty or 1.0,
uom=product_uom,
date=date_done,
)
)
result = product.lst_price
pricelist_rule = self.env["product.pricelist.item"].browse(
pricelist_rule_id
)
price_unit = pricelist_rule._compute_price(
product,
qty,
product_uom,
date_done,
currency=currency,
)

else:
result = product.lst_price
price_unit = product.lst_price

result = product._get_tax_included_unit_price(
company,
currency,
date_done,
"sale",
fiscal_position=fiscal_position,
product_price_unit=price_unit,
product_currency=currency,
)

return result

def _prepare_extra_move_vals(self, qty):
Expand Down
6 changes: 5 additions & 1 deletion stock_picking_invoicing/tests/test_picking_invoicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ def setUpClass(cls):
def test_0_picking_out_invoicing(self):
# setting Agrolait type to default, because it's 'contact' in demo data
nb_invoice_before = self.invoice_model.search_count([])
self.partner.write({"type": "invoice"})
# Test case to Get Price Unit to Invoice when Partner don't has Pricelist
self.partner.write({"type": "invoice", "property_product_pricelist": False})
picking = self.picking_model.create(
{
"partner_id": self.partner2.id,
Expand Down Expand Up @@ -845,6 +846,9 @@ def test_return_customer_picking(self):
# Force product availability
for move in picking_devolution.move_ids_without_package:
move.quantity_done = move.product_uom_qty
# Test case where the user inform the field, value
# infomed should has preferency over the PriceList or Sellers
move.price_unit = 11.1
picking_devolution.button_validate()
self.assertEqual(picking_devolution.state, "done", "Change state fail.")
wizard_obj = self.invoice_wizard.with_context(
Expand Down

0 comments on commit 7a7600c

Please sign in to comment.