2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-07-06 23:21:59 +00:00

Pricing bugs (#12305)

* bug fix for get_price method

- Remove unused argument moq
- Allow case where 'multiples' = False

* Error handling for convert_to

* Error handling for PartPricing.save

* Remove unused function

* Revert function definition

* coverage ignore
This commit is contained in:
Oliver
2026-07-06 22:09:12 +10:00
committed by GitHub
parent 436bfed234
commit ed62b5d9dd
3 changed files with 27 additions and 39 deletions
+12 -4
View File
@@ -162,13 +162,21 @@ def currency_exchange_plugins() -> Optional[list]:
def get_price(
instance,
quantity,
moq=True,
multiples=True,
currency=None,
moq: bool = True,
multiples: bool = True,
currency: Optional[str] = None,
break_name: str = 'price_breaks',
):
"""Calculate the price based on quantity price breaks.
Arguments:
instance: The model instance which contains the price break information
quantity: The quantity to calculate the price for
moq: If True, then minimum order quantity will be observed (CURRENTLY NOT IMPLEMENTED)
multiples: If True, then order multiples will be observed
currency: The currency code to use for the calculation (default is None)
break_name: The name of the price break field on the instance (default is 'price_breaks')
- Don't forget to add in flat-fee cost (base_cost field)
- If MOQ (minimum order quantity) is required, bump quantity
- If order multiples are to be observed, then we need to calculate based on that, too
@@ -185,7 +193,7 @@ def get_price(
return None
# Check if quantity is fraction and disable multiples
multiples = quantity % 1 == 0
multiples = multiples and (quantity % 1 == 0)
# Order multiples
if multiples:
+10 -4
View File
@@ -1388,21 +1388,27 @@ class PriceBreak(MetaMixin):
help_text=_('Unit price at specified quantity'),
)
def convert_to(self, currency_code):
def convert_to(self, currency_code: str, raise_error: bool = False):
"""Convert the unit-price at this price break to the specified currency code.
Args:
Arguments:
currency_code: The currency code to convert to (e.g "USD" or "AUD")
raise_error: If True, raise an error if the conversion fails. If False, return None.
"""
try:
converted = convert_money(self.price, currency_code)
except MissingRate:
except MissingRate: # pragma: no cover
InvenTree.exceptions.log_error('PriceBreak.convert_to')
logger.warning(
'No currency conversion rate available for %s -> %s',
self.price_currency,
currency_code,
)
return self.price.amount
if raise_error:
raise
return None
return converted.amount
+5 -31
View File
@@ -53,7 +53,7 @@ from common.settings import get_global_setting
from InvenTree import helpers, validators
from InvenTree.exceptions import log_error
from InvenTree.fields import InvenTreeURLField
from InvenTree.helpers import decimal2money, decimal2string, normalize
from InvenTree.helpers import decimal2string, normalize
from order import models as OrderModels
from order.status_codes import (
PurchaseOrderStatus,
@@ -3001,15 +3001,12 @@ class PartPricing(common.models.MetaMixin):
try:
self.update_overall_cost()
except Exception:
# If something has happened to the Part model, might throw an error
pass
try:
super().save(*args, **kwargs)
except Exception:
# This error may be thrown if there is already duplicate pricing data
pass
log_error('PartPricing.save')
logger.error(
"Could not save PartPricing for part '%s' to the database", self.part
)
def update_bom_cost(self, save=True):
"""Recalculate BOM cost for the referenced Part instance.
@@ -4426,29 +4423,6 @@ class BomItem(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel):
return required
@property
def price_range(self, internal=False):
"""Return the price-range for this BOM item."""
# get internal price setting
use_internal = get_global_setting('PART_BOM_USE_INTERNAL_PRICE', False)
p_range = self.sub_part.get_price_range(
self.quantity, internal=use_internal and internal
)
if p_range is None:
return p_range
p_min, p_max = p_range
if p_min == p_max:
return decimal2money(p_min)
# Convert to better string representation
p_min = decimal2money(p_min)
p_max = decimal2money(p_max)
return f'{p_min} to {p_max}'
@receiver(post_save, sender=BomItem, dispatch_uid='update_bom_build_lines')
def update_bom_build_lines(sender, instance, created, **kwargs):