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:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user