Open gabesullice opened 5 years ago
Thanks for writing this up. I will work to clarify and extend as needed.
Here is step 1 to define the data model and workflow. I am working backwards to get to a user story like statement
A cart is an order which is in a draft state and has the cart boolean marked as true
. The latter option is part of our CartProvider
and CartManager
APIs. Cart can be considered as a module that provides access control and management to non-elevated users.
An order has the following entity references:
An order item represents something that has been purchased and belongs to one order. The order item's bundle defines what purchasable entity type_ it references. An order item may not reference any purchasable entities. The default purchasable entity available is there Product Variation entity. Although any entity implementing PurchasableEntityInterface
is allowed. We rely heavily upon the PurchasableEntityInterface
class for order item relationships to products.
NOTE we do not have any kind of validation ensuring that the order item type references a class implementing this class. Only in Drupal's form validation. I should open an issue for this.
This is an outline of the add to cart flow, and understanding how a purchasable entity becomes attached to a cart as an order item.
Notes:
::createFromPurchasableEntity
. This created an order item with the bundle requested by the purchasable entity. The unit price is set from the purchasable entity's price.CartProvider
is used to check if a cart exists for the resolved order type and current store.CartManager
CartManager
handles combining existing order items to update their quantity, if requested, versus creating duplicate order items. It also fires an event to allow users to react to an add to cart event.We do not just directly call Order::addItem
or Order::get('order_items)::appendItem()
Relevant PHP interfaces we use for interacting with carts.
Here is a go at writing down some constraints for the operations
NOTE while this is out of the box behavior, generally a site should be configured to prevent multiple carts. Such as re-assigning an order if the store changes, or ignoring if changing stores is not expected behavior. However multiple carts can be a requirement, such as B2B scenarios.
It should be possible to add an item to a user's cart.
It should be possible to remove an item from a cart
CartManager
service from the PHP based API.It should be possible to remove all items from a cart
CartManager
service from the PHP based API.It should be possible to change the quantity of an item in a cart
It should be possible to update the quantities of all items in a cart
Non requirements, documented for clarity:
It'd be great to have a clearly defined set of requirements for a decoupled cart API.
Like:
Are all of these requirements? Can some of them be removed? Did I miss constraints?
What's the data model? What entity types are involved? A user entity. A cart entity (with bundles?), an order item entity?
How do those entities relate to one another? Via entity reference fields? Something else?
From there, I'd love to work out a spec for a cart API. Rather than starting from the implementation, that would help me know how I could best help you.
A spec would make it more clear to me what public JSON:API PHP APIs are needed than reverse engineering an experimental implementation.
I'm sure that what is easiest to get working today is not a 1:1 match to what would be easiest with an explicitly designed API.