From ef8fd5c5f7e1978f14b7ffa236e5a23fea63b645 Mon Sep 17 00:00:00 2001 From: agudermann <47318461+ArneGudermann@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:50:23 +0200 Subject: [PATCH] feat: Implement `discount_remove` (#24) Co-authored-by: Sven Eberth --- src/viur/shop/modules/api.py | 4 +- src/viur/shop/modules/cart.py | 2 +- src/viur/shop/modules/discount.py | 65 ++++++++++++++++++++++++++++++ src/viur/shop/skeletons/article.py | 1 - src/viur/shop/skeletons/cart.py | 6 ++- 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/viur/shop/modules/api.py b/src/viur/shop/modules/api.py index 346e7cd..e6f1c22 100644 --- a/src/viur/shop/modules/api.py +++ b/src/viur/shop/modules/api.py @@ -367,10 +367,10 @@ def discount_add( def discount_remove( self, *, - discount_key: str | db.Key, ): - ... + discount_key = self._normalize_external_key(discount_key, "discount_key") + return JsonResponse(self.shop.discount.remove(discount_key)) @exposed def shipping_list( diff --git a/src/viur/shop/modules/cart.py b/src/viur/shop/modules/cart.py index 6359532..c6edc2a 100644 --- a/src/viur/shop/modules/cart.py +++ b/src/viur/shop/modules/cart.py @@ -1,3 +1,4 @@ +import pprint import typing as t # noqa import viur.shop.types.exceptions as e @@ -499,7 +500,6 @@ def get_discount_for_leaf( raise InvalidStateError(f"{pk=} doesn't exist!") if discount := skel["discount"]: discounts.append(discount["dest"]) - logger.debug(f"{discounts = }") return discounts def add_new_parent(self, leaf_skel, **kwargs): diff --git a/src/viur/shop/modules/discount.py b/src/viur/shop/modules/discount.py index efa8bb8..484a574 100644 --- a/src/viur/shop/modules/discount.py +++ b/src/viur/shop/modules/discount.py @@ -5,6 +5,7 @@ from viur.core.prototypes import List from viur.core.skeleton import SkeletonInstance from viur.shop.types import * +from viur.shop.skeletons.discount_condition import DiscountConditionSkel from .abstract import ShopModuleAbstract from ..globals import SHOP_LOGGER from ..types.dc_scope import DiscountValidator @@ -207,3 +208,67 @@ def current_automatically_discounts(self) -> list[SkeletonInstance]: discounts.append(skel) logger.debug(f'current {discounts=}') return discounts + + def remove( + self, + discount_key: db.Key, + ) -> t.Any: + if not isinstance(discount_key, db.Key): + raise TypeError(f"discount_key must be an instance of db.Key") + cart_key = self.shop.cart.current_session_cart_key # TODO: parameter? + + discount_skel = self.viewSkel() + + if not discount_skel.fromDB(discount_key): + raise errors.NotFound + try: + # Todo what we do when we have more than more condition + application_domain = discount_skel["condition"][0]["dest"]["application_domain"] + except KeyError: + raise InvalidStateError("application_domain not set") + + if discount_skel["discount_type"] == DiscountType.FREE_ARTICLE: + for cart_skel in self.shop.cart.get_children(parent_cart_key=cart_key): + if cart_skel["discount"] and cart_skel["discount"]["dest"]["key"] == discount_skel["key"]: + break + else: + raise errors.NotFound + self.shop.cart.cart_remove( + cart_key=cart_skel["key"] + ) + + return { # TODO: what should be returned? + "discount_skel": discount_skel} + + elif application_domain == ApplicationDomain.BASKET: + self.shop.cart.cart_update( + cart_key=cart_key, + discount_key=None + ) + return { # TODO: what should be returned? + "discount_skel": discount_skel, + } + + elif application_domain == ApplicationDomain.ARTICLE: + node_skels = ( + self.shop.cart.viewSkel("node").all() + .filter("parentrepo =", cart_key) + .filter("discount.dest.__key__ =", discount_key) + .fetch(100) + ) + + logger.debug(f"<{len(node_skels)}>{node_skels=}") + for node_skel in node_skels: + # TODO: remove node, if no custom name, shipping, etc. is set? remove_parent flag? + self.shop.cart.cart_update( + cart_key=node_skel["key"], + discount_key=None, + ) + if not node_skels: + raise errors.NotFound("Discount not used by any cart") + return { # TODO: what should be returned? + "node_skels": node_skels, + "discount_skel": discount_skel, + } + + raise errors.NotImplemented(f'{discount_skel["discount_type"]=} is not implemented yet :(') diff --git a/src/viur/shop/skeletons/article.py b/src/viur/shop/skeletons/article.py index efe47ba..111bf80 100644 --- a/src/viur/shop/skeletons/article.py +++ b/src/viur/shop/skeletons/article.py @@ -92,7 +92,6 @@ def shop_price_(self) -> Price: compute=Compute(lambda skel: skel.shop_price_.to_dict(), ComputeInterval(ComputeMethod.Always)) ) shop_price.type = JsonBone.type - shop_shipping = RawBone( # FIXME: JsonBone doesn't work (https://github.com/viur-framework/viur-core/issues/1092) compute=Compute( lambda skel: make_json_dumpable(SHOP_INSTANCE.get().shipping.choose_shipping_skel_for_article(skel)), diff --git a/src/viur/shop/skeletons/cart.py b/src/viur/shop/skeletons/cart.py index f66902e..e8443cb 100644 --- a/src/viur/shop/skeletons/cart.py +++ b/src/viur/shop/skeletons/cart.py @@ -6,6 +6,7 @@ from viur.core.skeleton import SkeletonInstance from viur.shop.types import * from ..globals import SHOP_INSTANCE, SHOP_LOGGER +from ..types.response import make_json_dumpable logger = SHOP_LOGGER.getChild(__name__) @@ -294,11 +295,14 @@ def price_(self) -> Price: shipping = RawBone( # FIXME: JsonBone doesn't work (https://github.com/viur-framework/viur-core/issues/1092) compute=Compute( - lambda skel: SHOP_INSTANCE.get().shipping.choose_shipping_skel_for_article(skel.article_skel_full), + lambda skel: make_json_dumpable( + SHOP_INSTANCE.get().shipping.choose_shipping_skel_for_article(skel.article_skel_full) + ), ComputeInterval(ComputeMethod.Always)), ) shipping.type = JsonBone.type + @classmethod def toDB(cls, skelValues: SkeletonInstance, update_relations: bool = True, **kwargs) -> db.Key: return super().toDB(skelValues, update_relations, **kwargs)