In the original module model (which I believe still will work) we created licenses attached to a line item (order item) when a licensable product was added to cart, and then activated it at checkout. This issue deals with the early-stage automation around unactivated licenses, which are essentially stubs:
1. Create a license when a licensable order item is saved with a licensable product (if the order item doesn't have an associated license yet) and attach the license to the order item.
2. When an order item is removed from the cart or deleted, deleted the associated license if it has not yet been activated.
3. When a cart-status order w/ licenses attached is canceled, delete all unactivated licenses associated with its order items (?)
I'm trying to think about if #3 will break anything.
Comment | File | Size | Author |
---|---|---|---|
#20 | 2879263-20.commerce_license.License-creationdestruction-logic.patch | 8.27 KB | joachim |
#19 | 2879263-19.commerce_license.License-creationdestruction-logic.patch | 6.74 KB | joachim |
Comments
Comment #2
Kazanir CreditAttribution: Kazanir at Platform.sh for Acro Commerce commentedComment #3
joachim CreditAttribution: joachim at Torchbox commentedThis should probably be done with event subscribers, as that's what Commerce is using internally for things that happen when an order changes state.
See OrderReceiptSubscriber, and CartEventSubscriber for relevant examples.
> 1. Create a license when a licensable order item is saved with a licensable product (if the order item doesn't have an associated license yet) and attach the license to the order item.
The event for this is CartEvents::CART_ENTITY_ADD.
> When an order item is removed from the cart or deleted, deleted the associated license if it has not yet been activated.
CartEvents::CART_ORDER_ITEM_REMOVE
> 3. When a cart-status order w/ licenses attached is canceled, delete all unactivated licenses associated with its order items (?)
commerce_order.cancel.post_transition
Comment #4
joachim CreditAttribution: joachim at Torchbox commented> In the original module model (which I believe still will work) we created licenses attached to a line item (order item) when a licensable product was added to cart, and then activated it at checkout
This is maybe a stupid question, but what's the reason for all the synchronizing on adding and removing to cart?
It seems to me it would be simpler to only create the license when an order reaches the 'completed' state, as there would then be only one event to react to.
Comment #5
joachim CreditAttribution: joachim at Torchbox commentedAssigning to myself, as I've made a start on the code for this.
Comment #6
joachim CreditAttribution: joachim at Torchbox commentedI've hit a few bumps in the road:
1. For orders which are using a workflow with a fulfillment state, should the license be activated on reaching the 'fulfillment' state, or the 'completed' state? #2894796: clarify difference between 'fulfillment' and 'completed' order states
2. Commerce's order workflows use different transition names for the transitions that take the order to the 'completed' state. Because of this, and because State Machine fires events named for the transition rather than the state, we would need to subscribe to a lot of different events just for activating a license. #2894811: different workflows reach 'completed' state in different transition names, makes it hard to react to events, #2894810: Fire events named after the destination state rather than the transition name.
Comment #7
joachim CreditAttribution: joachim at Torchbox commentedHere's my work in progress. I think it's best to leave it here until #4 and #6 are resolved.
Comment #8
joachim CreditAttribution: joachim at Torchbox commentedOk so bojanz has replied at #2894796: clarify difference between 'fulfillment' and 'completed' order states, and says that we activate the license in the 'fulfillment' state, and also that in order to ensure the order gets to that state, we need to force the order to use one of the workflows that has it.
Questions:
- how does a product variation force an order to use a non-standard workflow?
- do we use the fulfillment workflow, or the fulfillment with validation?
Comment #9
chrisrockwell CreditAttribution: chrisrockwell commented[edit: hrm, I made a backwards interdiff] Just some clean-up on the work in progress.
I think that's a site-specific question. The one I'm working on does not need validation before going into "Fulfillment" - but I can certainly see use-cases for having a review process (I think some hosting companies do this actually).
By creating an order type (A) that uses the workflow, and then an order item type (B) that has Order Type (A), and then a Variation Type that uses order item type (B).
I'm just getting my feet wet here, but I feel like the best place to address this:
Or I could be completely wrong :D.
Comment #10
chrisrockwell CreditAttribution: chrisrockwell commentedA better interdiff
Comment #11
joachim CreditAttribution: joachim as a volunteer commented> - how does a product variation force an order to use a non-standard workflow?
I had a look at Commerce Shipping. It forces the order to use a non-standard workflow by telling the site builder in the README that they need to change workflow on the default order type... I don't think this is very robust!
Comment #12
joachim CreditAttribution: joachim as a volunteer commentedSee also #2894805: add a way to check content entities for bundle traits.
In the event subscriber methods, we need to check whether an order's items are for license products.
Comment #13
chrisrockwell CreditAttribution: chrisrockwell commentedI'm poking around in here now. It seems like a license entity should be created in a subscriber to
commerce_order.place.post_transition
, which would _I think_ mean we're in the fulfillment state (or some place in-between place and fulfillment).In a subscriber to
commerce_order.fulfillment.post_transition
the license is activated/synchronized and thenStateItem::applyTransition
is used to move the order to completed.Does this sound right?
Comment #14
joachim CreditAttribution: joachim at Torchbox commentedI've done some more work on this.
It's not complete, as we need to set the license ID on the order item, and getting a field onto the order item for that is #2879276: Licensable order item types & fields.
Also, my events are not currently triggering and I don't know why...
Comment #15
chrisrockwell CreditAttribution: chrisrockwell commentedI believe this should be
arguments: ['@entity_type.manager']
. Might be why your event is subscribing.Comment #16
joachim CreditAttribution: joachim at Torchbox commentedUnassigning myself, as I'm stuck on this.
Comment #17
chrisrockwell CreditAttribution: chrisrockwell commented`fulfillment` should be `fulfill` ( I can update the patch later). I can't find an example of completed post transition, but that is not firing for me after "Fulfilling" the order.
Comment #18
joachim CreditAttribution: joachim at Torchbox commentedThanks for spotting that! Saved me probably half an hour of headdesking! :)
Here is an updated patch. This now creates a new license when I put an order through checkout! Hurrah!
However, I'm still really unclear on the whole picture of how a license's workflow syncs up with an order's workflow:
- I'm creating the license then activating it in the order's fulfillment state
-- how does a license plugin indicate that there is a problem with activating the license?
-- how do we indicate to the order that there is a problem?
-- how do we indicate to the order that the license was activated, and the order may now advance to the complete state? With my test orders, they stay in fulfillment state and the only way I can see to advance them is to set it manually in the order form. Surely with an order of only digital products that shouldn't be needed?
Comment #19
joachim CreditAttribution: joachim at Torchbox commentedUpdated patch.
I still have no idea about the questions in #18, but I am thinking I should commit this now so that licenses get created with orders and I can keep going with other issues (#2899878: add a method to License to set values from a configured plugin is next).
If there are parts of the synchronizing logic I've got wrong, that can be changed in follow-ups.
Comment #20
joachim CreditAttribution: joachim at Torchbox commentedCommitting this so we have the basic functionality here, so I can move on and commit further patches. Filed #2900325: revisit and extend license creation/destruction logic in sync with cart/order lifecycle as a follow-on to resolve the questions from #18 and other matters such as synchronized licenses.