Source code for shuup.front.basket.storage

# -*- coding: utf-8 -*-
# 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 logging
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

from shuup.core.basket.storage import BaseDatabaseBasketStorage, BasketStorage
from shuup.front.models import StoredBasket
from shuup.utils.analog import LogEntryKind

LOGGER = logging.getLogger(__name__)


[docs]class DirectSessionBasketStorage(BasketStorage): def __init__(self): if settings.SESSION_SERIALIZER == "django.contrib.sessions.serializers.JSONSerializer": # pragma: no cover raise ImproperlyConfigured( "Error! `DirectSessionBasketStorage` will not work with the JSONSerializer session serializer." )
[docs] def save(self, basket, data): stored_basket = DictStoredBasket.from_basket_and_data(basket, data) basket.request.session[basket.basket_name] = stored_basket.as_dict()
def _load_stored_basket(self, basket): stored_basket_dict = basket.request.session.get(basket.basket_name) if not stored_basket_dict: return None return DictStoredBasket.from_dict(stored_basket_dict)
[docs] def delete(self, basket): basket.request.session.pop(basket.basket_name, None)
[docs]class DictStoredBasket(object): def __init__(self, id, shop_id, currency, prices_include_tax, data): self.id = id self.shop_id = shop_id self.currency = currency self.prices_include_tax = prices_include_tax self.data = data or {} @classmethod
[docs] def from_basket_and_data(cls, basket, data): return cls( id=(getattr(basket, "id", None) or basket.basket_name), shop_id=basket.shop.id, currency=basket.currency, prices_include_tax=basket.prices_include_tax, data=data, )
@classmethod
[docs] def from_dict(cls, mapping): return cls(**mapping)
[docs] def as_dict(self): return { "id": self.id, "shop_id": self.shop_id, "currency": self.currency, "prices_include_tax": self.prices_include_tax, "data": self.data, }
[docs]class DatabaseBasketStorage(BaseDatabaseBasketStorage): model = StoredBasket def _get_session_key(self, basket): return "basket_%s_key" % basket.basket_name
[docs] def get_basket_kwargs(self, basket): # Lets first try to get basket kwargs from basket request session basket_kwargs = basket.request.session.get(self._get_session_key(basket)) if not basket_kwargs: # Fallback to basket customer and key combination basket_kwargs = {"key": basket.key} return basket_kwargs
[docs] def save(self, basket, data): stored_basket = super(DatabaseBasketStorage, self).save(basket, data) basket_kwargs = {"pk": stored_basket.pk, "key": stored_basket.key} basket.request.session[self._get_session_key(basket)] = basket_kwargs
[docs] def delete(self, basket): super(DatabaseBasketStorage, self).delete(basket) basket.request.session.pop(self._get_session_key(basket), None)
[docs] def finalize(self, basket): super(DatabaseBasketStorage, self).finalize(basket) basket.request.session.pop(self._get_session_key(basket), None)
def _load_stored_basket(self, basket): stored_basket = super(DatabaseBasketStorage, self)._load_stored_basket(basket) if not stored_basket.pk and self.get_basket_kwargs(basket): basket.request.session.pop(self._get_session_key(basket), None) return stored_basket
[docs] def basket_exists(self, key, shop): return self.model.objects.filter(key=key, shop=shop).exists()
def _get_key_for_logs(self, basket): basket_kwargs = self.get_basket_kwargs(basket) return "%s%s" % ("stored_basket_key:", basket_kwargs["key"])
[docs] def add_log_entry(self, basket, message, extra={}, kind=LogEntryKind.NOTE): try: if getattr(basket, "shop", None): identifier = self._get_key_for_logs(basket) basket.shop.add_log_entry(kind=kind, identifier=identifier, message=message, extra=extra) except Exception: # This might get called on important checkout related flows it is not # good idea to interrupt the business if for some reason this logging # fails. LOGGER.error("Adding log entry to stored basket failed.")
[docs] def get_log_entries(self, basket): identifier = self._get_key_for_logs(basket) if getattr(basket, "shop", None): return basket.shop.log_entries.filter(identifier=identifier) return []