Continuing discussion from:
- Customer can have a Standing / Repeating order
- Enterprise can create a Series of recurring Order Cycles
Overview
Standing Orders is a feature request that has been hanging around for a long time, it has very wide appeal, but the full build is also likely to be reasonably complex. We are trying to get some momentum and a consensus on a first cut to finally implement something.
I’ve tried to describe a full set of user stories that have been discussed so far, so feel free to add any you can think of. More on the specifics of the data model and logic to come…
Full List Of User Stories (add more if you have more)
As an Enterprise User
- I can create a representation of the way my order cycles repeat, by organising them into a set
- I can see a list of my OC sets
- I can see the list of OCs in a given set
- I can add/remove OCs from a set
- For a given set of OCs
- I can create a standing order for a given customer
- Contains all relevant information, products, quantities, addresses, shipping and payment methods
- I can cancel individual future orders for a customer
- I can alter the standing order (ie. all future orders)
- I can cancel the standing order (ie. all future orders)
- I can restrict which products are available to place in a standing order
- I can alter an individual future order
- Add/remove products
- Change payment/shipping methods
- Add payments
- I can alter future orders in bulk (without necessarily altering the standing order itself)
- Add/Remove products
- Change Shipping/Payment Methods
- Add payments
- I can visualise past and future orders for all customers in a single interface
- I’m envisioning a table with customers on one axis, OrderCycles on the other, and the order total at the intersection, which can be clicked on to reveal a modal with more detailed information about the order
- Including a “Product View” where orders are represented by in the interface depending on which of a defined set of products they contain (Baw Baw Food Hub use case - Small, Medium, Large Veggie Boxes)
As a Customer
- I can set up a standing order from scratch (without necessarily needing to place an order first)
- can set products, quantities, addresses, shipping and payment methods
- I can select an existing order to use as a ‘template’ for a standing order
- Both from my account page, and in the order confirmation page
- I can cancel my standing order
- I can alter my standing order: ie. the products, quantities, shipping and payment methods
- I can cancel an individual future order
- I can optionally alter an instance of my standing order (ie. for a given order cycle), by visiting the shopfront
- ie. it will automatically be loaded for alteration when I hit the shopfront
- I can do nothing while an OC is open, and my order will be processed automatically when each OC closes
- I can receive standard order confrimation notifications for my standing orders via email
- I can understand when products in my standing order become unavailable
- When I visit the site to alter my standing order
- Information is displayed to me in the shopfront
- When I don’t visit the site during an order cycle
- The confirmation email I receive will inform me of the unavailability of certain products
Proposed Model
- Create the ShopConfiguration model (as mentioned in Order Cycles 2.0), for grouping OCs together
- Has many StandingOrders
- Create a new model called StandingOrder
- Belongs to an OrderCycleSet and a Customer
- Holds a list of StandingLineItems, as well as informatino like preferred payment method, shipping method and address
- Create a new model called StandingLineItems
- Belongs to StandingOrder and Variant
- Basically just holds a quantitity for the specified variant
- Associate Orders to the Standing Order from which they originated, allows them to be identified as a standing order, and for the StandingOrder to determine whether an order has been initialised for a given OC
Notes on Logic
- Using the hybrid of StandingOrder and Spree::Order, we get the best of both worlds
- When no future changes are required - StandingOrders can take care of themselves
- When future changes are required - we can instantiate an actual Spree::Order and alter it as we like
- no need to choose between the two
- Will need to use events around OC Opening and Closing - I think Delayed::Job can handle this?
- On open, instantiate all relevant standing orders as actual Spree::Order instances
- On close, if the customer has not processed their order via the shopfront, it is processed as it stands
- The fact that an order belongs to a StandingOrder indicates that it should be processed on OC close if not processed manually by the user first