shuup.core.pricing package
Submodules
shuup.core.pricing.default_pricing module
- class shuup.core.pricing.default_pricing.DefaultPricingModule[source]
Bases:
PricingModule- identifier = 'default_pricing'
- name = 'Default Pricing'
Module contents
Shuup modular product pricing functionality.
The pricing module in use is declared by the
SHUUP_PRICING_MODULE setting. The
default is a pricing module that always prices everything to be free.
The base distribution contains shuup.customer_group_pricing, which is an
useful pricing module for many cases.
To acquire an instance of the current pricing module, use
get_pricing_module.
In brief, a pricing module is able to price a product based on a
context; what exactly a context contains is determined by the module
in question. You can construct a context from a request by calling the
module’s get_context_from_request method, or
for more advanced uses, when you do not have access to an HTTP request,
get_context_from_data.
After you have acquired the module and a context, you can calculate
prices for a product with the module’s
get_price_info method.
(Product objects contain the
convenience methods
get_price_info,
get_price,
and get_base_price
which do these steps for you.)
If you have multiple products, it will likely be more efficient –
depending on the implementation of the module – to use the
get_price_infos method.
TODO: document the concepts of base price and the pricing steps API. TODO: caching.
- class shuup.core.pricing.DiscountModule
Bases:
object- abstractmethod discount_price(context: PricingContext, product: Product | int, price_info: PriceInfo) PriceInfo[source]
Discount given price of given product. :param context: Pricing context to operate in :param product: Product in question or its id :param price_info: Price to discount :return: A new instance of a discounted price
- discount_prices(context: PricingContext, products: Iterable[Product | int], price_infos: Dict[int, PriceInfo]) Dict[int, PriceInfo][source]
Discount a bunch of prices.
- Parameters:
context (shuup.core.pricing.PricingContext) – Pricing context to operate in
products (Iterable[shuup.core.models.Product|int]) – Products in question or their ids
- Return type:
- get_pricing_steps(context: PricingContext, product: Product | int, steps: Iterable[PriceInfo]) Iterable[PriceInfo][source]
Get discounted pricing steps for given product.
Base class version just discounts all the given steps with
discount_price, but another module could add more steps and should do so, if the module introduces any pricing steps.- Parameters:
context (shuup.core.pricing.PricingContext) – Pricing context to operate in
product (shuup.core.models.Product|int) – Product in question or its id
- Return type:
- get_pricing_steps_for_products(context: PricingContext, products: Iterable[Product | int], steps: Iterable[PriceInfo]) Dict[int, Iterable[PriceInfo]][source]
Get discounted pricing steps for a bunch of products.
- Parameters:
context (shuup.core.pricing.PricingContext) – Pricing context to operate in
products (Iterable[shuup.core.models.Product|int]) – Products in question or their ids
- Return type:
- index_shop_product(shop_product: ShopProduct | int, **kwargs)[source]
Index the shop product discounts
- shuup.core.pricing.get_discount_modules()
Get a list of configured discount module instances.
- Return type:
- shuup.core.pricing.get_price_info(context, product, quantity=1)
Get price info of product for given quantity.
Returned
PriceInfoobject contains calculatedpriceandbase_price. The calculation of prices is handled in the current pricing module and possibly configured discount modules.- Parameters:
product (shuup.core.models.Product|int) –
Productobject or id ofProduct- Return type:
- shuup.core.pricing.get_price_infos(context, products, quantity=1)
Get PriceInfo objects for a bunch of products.
Returns a dict with product id as key and PriceInfo as value.
May be faster than doing
get_price_infofor each product.- Parameters:
products (Iterable[shuup.core.models.Product|int]) – List of product objects or id’s
- Return type:
- shuup.core.pricing.get_pricing_module()
- Return type:
- shuup.core.pricing.get_pricing_steps(context, product)
Get context-specific list pricing steps for the given product.
Returns a list of PriceInfos, see
PricingModule.get_pricing_stepsfor description of its format.- Parameters:
product (shuup.core.models.Product|int) – Product or product id
- Return type:
- shuup.core.pricing.get_pricing_steps_for_products(context, products)
Get pricing steps for a bunch of products.
Returns a dict with product id as key and step data (as list of PriceInfos) as values.
May be faster than doing
get_pricing_stepsfor each product separately.
- class shuup.core.pricing.Price(value='0', *args, **kwargs)
Bases:
MoneyMoney amount with taxful/taxless info.
Taxful and taxless prices cannot be mixed in comparison or in calculations, i.e. operations like
x < yorx + yfor two Pricesxandywithx.includes_tax != y.includes_taxwill raise anUnitMixupError.In addition to
includes_taxinfo, Prices are Money and know theirvalueandcurrency. To get the bare Money amount of aPrice, use theamountproperty.Create new Money instance with given value and currency.
If no currency is given explicitly and
valuehas a property namedcurrency, then that will be used. Otherwise currency is a required argument and not passing one will raise a TypeError.- Parameters:
value (str|numbers.Number) – Value as string or number.
currency (str|None) – Currency as ISO-4217 code (3-letter string) or None.
- includes_tax = None
- class shuup.core.pricing.PriceDisplayOptions(include_taxes=None, show_prices=True)
Bases:
objectPrice display options.
Parameters on how prices should be rendered.
Initialize price display options.
- Parameters:
- property hide_prices
- class shuup.core.pricing.Priceful
Bases:
objectMixin to define price properties based on other price properties.
You must provide at least
quantity(Decimal)
and both
or both
You may also provide
tax_amount(Money)
to get various tax related properties.
Provided
base_unit_price,discount_amount,price,base_price, andtax_amountmust have compatible units (i.e. same taxness and currency).- Invariants:
price = base_unit_price * quantity - discount_amountdiscount_amount = base_price - pricediscount_rate = 1 - (price / base_price)discount_percentage = 100 * discount_rateunit_discount_amount = discount_amount / quantitytaxful_price = raw_taxless_price + tax_amounttax_rate = (raw_taxful_price.amount / raw_taxless_price.amount) - 1tax_percentage = 100 * tax_rate
- property base_price
Total price for the specified quantity excluding discount.
- Return type:
- property base_unit_price
Undiscounted unit price.
Note: If quantity is 0, will return
base_price.- Return type:
- property discount_amount
Amount of discount for the total quantity.
Normally positive or zero, but might also be negative if product is being sold with higher price than its normal price.
- Return type:
- property discount_percentage
Discount percentage, 100 meaning totally discounted.
See
discount_rate.- Return type:
- property discount_rate
Discount rate, 1 meaning totally discounted.
Note: Could be negative, when base price is smaller than effective price. Could also be greater than 1, when effective price is negative.
If base price is 0, will return 0.
- Return type:
- property discounted_unit_price
Unit price with discount.
If quantity is 0, will return
base_unit_price - discount_amount.- Return type:
- property is_discounted
Check if there is a discount in effect.
- Returns:
True, iff price < base price.
- property price
Total price for the specified quantity with discount.
For scenarios like below quantize the returned price.
base_unit_price * quantity - discount_amount 940.234529877 EUR (excl. tax) 1.000000000 0E-9 EUR (excl. tax) return 40.234529877000000000 EUR (excl. tax)
- Return type:
- property raw_taxful_price
- property raw_taxless_price
- property tax_percentage
decimal.Decimal
- Type:
rtype
- property tax_rate
decimal.Decimal
- Type:
rtype
- taxful_base_price
Taxful
base_price
- taxful_base_unit_price
Taxful
base_unit_price
- taxful_discount_amount
Taxful
discount_amount
- taxful_discounted_unit_price
Taxful
discounted_unit_price
- property taxful_price
TaxfulPrice
- Type:
rtype
- taxful_unit_discount_amount
Taxful
unit_discount_amount
- taxless_base_price
Taxless
base_price
- taxless_base_unit_price
Taxless
base_unit_price
- taxless_discount_amount
Taxless
discount_amount
- taxless_discounted_unit_price
Taxless
discounted_unit_price
- property taxless_price
TaxlessPrice
- Type:
rtype
- taxless_unit_discount_amount
Taxless
unit_discount_amount
- property unit_discount_amount
Discount amount per unit.
If quantity is 0, will return
discount_amount.- Return type:
- class shuup.core.pricing.PriceInfo(price, base_price, quantity, expires_on=None)
Bases:
PricefulObject for passing around pricing data of an item.
Initialize PriceInfo with prices and other parameters.
Prices can be taxful or taxless, but their types must match.
- Parameters:
price (Price) – Effective price for the specified quantity.
base_price (Price) – Base price for the specified quantity. Discounts are calculated based on this.
quantity (numbers.Number) – Quantity that the given price is for. Unit price is calculated by
discounted_unit_price = price / quantity. Note: Quantity could be non-integral (i.e. decimal).expires_on (numbers.Number|None) – Unix timestamp, comparable to values returned by
time.time, determining the point in time when the prices are no longer valid, or None if no expire time is set (which could mean indefinitely, but in reality, it just means undefined).
- __init__(price, base_price, quantity, expires_on=None)[source]
Initialize PriceInfo with prices and other parameters.
Prices can be taxful or taxless, but their types must match.
- Parameters:
price (Price) – Effective price for the specified quantity.
base_price (Price) – Base price for the specified quantity. Discounts are calculated based on this.
quantity (numbers.Number) – Quantity that the given price is for. Unit price is calculated by
discounted_unit_price = price / quantity. Note: Quantity could be non-integral (i.e. decimal).expires_on (numbers.Number|None) – Unix timestamp, comparable to values returned by
time.time, determining the point in time when the prices are no longer valid, or None if no expire time is set (which could mean indefinitely, but in reality, it just means undefined).
- base_price = None
- expires_on = None
- price = None
- quantity = None
- class shuup.core.pricing.PricingContext(shop, customer, time=None, basket=None, supplier=None)
Bases:
PricingContextableContext for pricing.
Initialize pricing context for shop and customer.
- class shuup.core.pricing.PricingContextable
Bases:
objectObject that is or can be converted to a pricing context.
Currently there exists two kind of
PricingContextableobjects:PricingContext`(and its subclasses) and `HttpRequest.Note
Expression
isinstance(request, PricingContextable)will return True for arequestwhich isHttpRequest, becauseHttpRequestis registered as a subclass of this abstract base class.This abstract base class is just a helper to allow writing simpler type specifiers, since we want to allow passing
HttpRequestas a pricing context even though it is not aPricingContext.
- class shuup.core.pricing.PricingModule
Bases:
object- get_context_from_data(shop, customer, time=None, **kwargs)[source]
Create pricing context from given arguments.
- Return type:
- get_context_from_request(request)[source]
Create pricing context from HTTP request.
This base class implementation does not use
requestat all.- Return type:
- abstractmethod get_price_info(context, product, quantity=1)[source]
Get price info for a given quantity of the product.
- Parameters:
product (shuup.core.models.Product|int) –
Productobject or id ofProduct.- Return type:
- get_price_infos(context, products, quantity=1)[source]
Get PriceInfo objects for a bunch of products.
Returns a dict with product id as key and PriceInfo as value.
May be faster than doing
get_price_infofor each product separately, since inheriting class may override this.- Parameters:
products (Iterable[shuup.core.models.Product|int]) – List of
Productobjects or id’s- Return type:
- get_pricing_steps(context, product)[source]
Get context-specific list pricing steps for the given product.
Returns a list of PriceInfos
[pi0, pi1, pi2, ...]where each PriceInfo object is at the border unit price change: unit price for0 <= quantity < pi1.quantity1ispi0.discounted_unit_price, and unit price forpi1.quantity <= quantity < pi2.quantityispi1.discounted_unit_price, and so on.If there are “no steps”, the return value will be a list of single PriceInfo object with the constant price, i.e.
[price_info].- Parameters:
product (shuup.core.models.Product|int) –
Productobject or id ofProduct.- Return type:
- get_pricing_steps_for_products(context, products)[source]
Get pricing steps for a bunch of products.
Returns a dict with product id as key and step data (as list of PriceInfos) as values.
May be faster than doing
get_pricing_stepsfor each product separately, since inheriting class may override this.
- identifier = None
- index_shop_product(shop_product: ShopProduct | int, **kwargs)[source]
Index the prices for the given shop product
- name = None
- pricing_context_class
alias of
PricingContext
- class shuup.core.pricing.TaxfulPrice(value='0', *args, **kwargs)
Bases:
PricePrice which includes taxes.
Check the base class,
Price, for more info.Create new Money instance with given value and currency.
If no currency is given explicitly and
valuehas a property namedcurrency, then that will be used. Otherwise currency is a required argument and not passing one will raise a TypeError.- Parameters:
value (str|numbers.Number) – Value as string or number.
currency (str|None) – Currency as ISO-4217 code (3-letter string) or None.
- includes_tax = True
- class shuup.core.pricing.TaxlessPrice(value='0', *args, **kwargs)
Bases:
PricePrice which does not include taxes.
Check the base class,
Price, for more info.Create new Money instance with given value and currency.
If no currency is given explicitly and
valuehas a property namedcurrency, then that will be used. Otherwise currency is a required argument and not passing one will raise a TypeError.- Parameters:
value (str|numbers.Number) – Value as string or number.
currency (str|None) – Currency as ISO-4217 code (3-letter string) or None.
- includes_tax = False