Source code for shuup.core.pricing._module

# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals

import abc
import six
from django.http import HttpRequest

from shuup.apps.provides import load_module

from ._context import PricingContext


def get_pricing_module():
    """
    :rtype: shuup.core.pricing.PricingModule
    """
    return load_module("SHUUP_PRICING_MODULE", "pricing_module")()


class PricingModule(six.with_metaclass(abc.ABCMeta)):
    identifier = None
    name = None
    pricing_context_class = PricingContext

[docs] def get_context(self, context): """ Create pricing context from pricing contextable object. :type context: PricingContextable :rtype: PricingContext """ if isinstance(context, self.pricing_context_class): return context elif isinstance(context, HttpRequest): return self.get_context_from_request(context) raise TypeError("Error! Not pricing contextable: %r." % (context,))
[docs] def get_context_from_request(self, request): """ Create pricing context from HTTP request. This base class implementation does not use `request` at all. :type request: HttpRequest :rtype: PricingContext """ return self.pricing_context_class( customer=request.customer, shop=request.shop, basket=getattr(request, "basket", None), supplier=getattr(request, "supplier", None), )
[docs] def get_context_from_data(self, shop, customer, time=None, **kwargs): """ Create pricing context from given arguments. :type shop: shuup.core.models.Shop :type customer: shuup.core.models.Contact :type time: datetime.datetime|None :rtype: PricingContext """ return self.pricing_context_class(shop=shop, customer=customer, time=time, **kwargs)
@abc.abstractmethod
[docs] def get_price_info(self, context, product, quantity=1): """ Get price info for a given quantity of the product. :param product: `Product` object or id of `Product`. :type product: shuup.core.models.Product|int :rtype: PriceInfo """ pass
[docs] def get_pricing_steps(self, context, product): """ 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 for ``0 <= quantity < pi1.quantity1`` is ``pi0.discounted_unit_price``, and unit price for ``pi1.quantity <= quantity < pi2.quantity`` is ``pi1.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]``. :param product: `Product` object or id of `Product`. :type product: shuup.core.models.Product|int :rtype: list[PriceInfo] """ return [self.get_price_info(context, product, quantity=1)]
[docs] def get_price_infos(self, 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 :func:`get_price_info` for each product separately, since inheriting class may override this. :param products: List of `Product` objects or id's :type products: Iterable[shuup.core.models.Product|int] :rtype: dict[int,PriceInfo] """ product_map = {getattr(x, "pk", x): x for x in products} return { product_id: self.get_price_info(context, product, quantity) for (product_id, product) in six.iteritems(product_map) }
[docs] def get_pricing_steps_for_products(self, 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 :func:`get_pricing_steps` for each product separately, since inheriting class may override this. :param products: List of `Product` objects or id's. :type products: Iterable[shuup.core.models.Product|int] :rtype: dict[int,list[PriceInfo]] """ product_map = {getattr(x, "pk", x): x for x in products} return { product_id: self.get_pricing_steps(context, product) for (product_id, product) in six.iteritems(product_map) }