11import typing as t # noqa
22
33from google .protobuf .message import DecodeError
4- from viur .core import current , db , errors , exposed , force_post
5- from viur .core .render .json .default import DefaultRender as JsonRenderer
64
75import viur .shop .types .exceptions as e
6+ from viur .core import current , db , errors , exposed , force_post
7+ from viur .core .render .json .default import DefaultRender as JsonRenderer
88from viur .shop .modules .abstract import ShopModuleAbstract
99from viur .shop .skeletons import ShippingSkel
1010from viur .shop .types import *
@@ -48,12 +48,22 @@ def article_add(
4848 article_key : str | db .Key ,
4949 quantity : int = 1 ,
5050 quantity_mode : QuantityMode = QuantityMode .REPLACE ,
51- parent_cart_key : str | db .Key ,
51+ parent_cart_key : str | db .Key | t . Literal [ "BASKET" ] = SENTINEL ,
5252 ** kwargs ,
5353 ):
54- """Add an article to the cart"""
54+ """Add an article to the cart
55+
56+ :param article_key: Key of the article to add.
57+ :param quantity: Quantity of the article to add.
58+ :param quantity_mode: Behavior of the quantity: absolute or relative valuation
59+ :param parent_cart_key: Key of the (sub) cart (node) to which
60+ this leaf will be added as a child.
61+ Use "BASKET" as key to use the basket of the current session.
62+ """
5563 article_key = self ._normalize_external_key (
5664 article_key , "article_key" )
65+ if parent_cart_key == "BASKET" :
66+ parent_cart_key = self .shop .cart .get_current_session_cart_key (create_if_missing = True )
5767 parent_cart_key = self ._normalize_external_key (
5868 parent_cart_key , "parent_cart_key" )
5969 assert isinstance (quantity_mode , QuantityMode )
@@ -73,12 +83,23 @@ def article_update(
7383 article_key : str | db .Key ,
7484 quantity : int ,
7585 quantity_mode : QuantityMode = QuantityMode .REPLACE ,
76- parent_cart_key : str | db .Key ,
86+ parent_cart_key : str | db .Key | t . Literal [ "BASKET" ] = SENTINEL ,
7787 ** kwargs ,
7888 ):
79- """Update an existing article in the cart"""
89+ """Update an existing article in the cart
90+
91+ :param article_key: Key of the article to update.
92+ Note: This is not the key of the leaf skel!
93+ :param quantity: Quantity of the article to update.
94+ :param quantity_mode: Behavior of the quantity: absolute or relative valuation
95+ :param parent_cart_key: Optional. Key of the (sub) cart (node) to which
96+ this leaf will be moved to as a child.
97+ Use "BASKET" as key to use the basket of the current session.
98+ """
8099 article_key = self ._normalize_external_key (
81100 article_key , "article_key" )
101+ if parent_cart_key == "BASKET" :
102+ parent_cart_key = self .shop .cart .get_current_session_cart_key (create_if_missing = True )
82103 parent_cart_key = self ._normalize_external_key (
83104 parent_cart_key , "parent_cart_key" )
84105 assert isinstance (quantity_mode , QuantityMode )
@@ -260,19 +281,33 @@ def cart_clear(
260281 def basket_list (
261282 self ,
262283 ):
263- """List the children of the basket (the cart stored in the session)"""
284+ """List the children of the basket (the cart stored in the session)
285+
286+ :raises errors.PreconditionFailed: If no basket created yet for this session
287+ """
288+ if self .shop .cart .current_session_cart_key is None :
289+ raise errors .PreconditionFailed ("No basket created yet for this session" ) # TODO(discuss): explicit?
290+ return [] # TODO(discuss): implicit?
264291 return self .cart_list (cart_key = self .shop .cart .current_session_cart_key )
265292
266293 @exposed
267294 def basket_view (
268295 self ,
296+ * ,
297+ create_if_missing : bool = False ,
269298 ):
270299 """View the basket (the cart stored in the session) itself
271300
301+ :param create_if_missing: Create the basket if not already created for this session
302+ :raises errors.PreconditionFailed: If no basket created yet for this session (and it should not be created)
303+
272304 See also :meth:`basket_view` to view any cart.
273305 """
306+ cart_key = self .shop .cart .get_current_session_cart_key (create_if_missing = create_if_missing )
307+ if cart_key is None :
308+ raise errors .PreconditionFailed ("No basket created yet for this session" )
274309 return JsonResponse (self .shop .cart .cart_get (
275- cart_key = self . shop . cart . current_session_cart_key , skel_type = "node" ,
310+ cart_key = cart_key , skel_type = "node" ,
276311 ))
277312
278313 @exposed
@@ -506,6 +541,8 @@ def _normalize_external_key(
506541 return None
507542 elif not external_key :
508543 raise InvalidKeyException (external_key , parameter_name )
544+ if isinstance (external_key , db .Key ):
545+ return external_key
509546 try :
510547 return db .Key .from_legacy_urlsafe (external_key )
511548 except (ValueError , DecodeError ): # yes, the exception really comes from protobuf...
0 commit comments