solidus icon indicating copy to clipboard operation
solidus copied to clipboard

Mark a shipment as canceled if all the inventory units have been canceled

Open BenMorganIO opened this issue 2 years ago β€’ 8 comments

Summary

I noticed that if a multi-shipment order goes through and you cancel one of the shipments, an order recalculation will set the shipment as pending/ready. See:

https://github.com/solidusio/solidus/blob/main/core/app/models/spree/shipment.rb#L208

This is because it's only checking if the order is canceled. While this is a correct method to check if a shipment should be marked as canceled, it falls short if it's only 1 shipment in an order that needs to be canceled out of many. If I cancel a shipment, then the shipment will be marked as shipped and that can be quite surprising for customers and admins.

Instead, let's increase the guarantee on canceling a shipment for now by checking if the order is canceled or all of the inventory units for said shipment have been canceled.

I've also updated the logic for checking if the state should be set to shipped. While the check for shipped? remains to ensure immutability, we also mark a shipment as shipped just like in the Spree::OrderCancellations if some of the inventory units are shipped and some are canceled. See:

https://github.com/solidusio/solidus/blob/main/core/app/models/spree/order_cancellations.rb#L121

In the future, I think it would be better that when a shipment is canceled, an inventory unit cancellation should be done on the inventory units it's responsible for. That would help create a guarantee for resolving the bug highlighted above but this is a much larger change. For now, just marking a shipment as canceled when the inventory units have been canceled and matching the existing order cancelation logic is progress in the right direction.

Checklist

Check out our PR guidelines for more details.

The following are mandatory for all PRs:

The following are not always needed:

  • πŸ“– I have updated the README to account for my changes.
  • πŸ“‘ I have documented new code with YARD.
  • πŸ›£οΈ I have opened a PR to update the guides.
  • βœ… I have added automated tests to cover my changes.
  • πŸ“Έ I have attached screenshots to demo visual changes.

BenMorganIO avatar Jul 05 '23 03:07 BenMorganIO

Codecov Report

Merging #5220 (3bde83e) into main (5f9c960) will decrease coverage by 0.01%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #5220      +/-   ##
==========================================
- Coverage   88.67%   88.66%   -0.01%     
==========================================
  Files         564      564              
  Lines       13894    13898       +4     
==========================================
+ Hits        12320    12323       +3     
- Misses       1574     1575       +1     
Impacted Files Coverage Ξ”
core/app/models/spree/order_cancellations.rb 95.74% <100.00%> (-2.04%) :arrow_down:
core/app/models/spree/shipment.rb 93.52% <100.00%> (+0.07%) :arrow_up:

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more

codecov[bot] avatar Jul 05 '23 03:07 codecov[bot]

Thanks for working on this @BenMorganIO! I tried this locally with @MassimilianoLattanzio, who worked on something similar for one of our stores.

We think this works, but we are not sure about if it's a good thing to consider a shipped shipment as canceled if all of its content has been canceled. E.g. I ship an empty package by mistake, so I will cancel all the items in it. Is it correct to consider that shipment canceled, even if it has been shipped? Yes, there's always the carton that represents the shipped shipment, but maybe in this case it's not clear what actually happened looking at the order's shipment state. What do you think?

Also, I think there was another issue (already there, not related to this PR), because we are updating the shipment date of the shipment after canceling one of the items present in a shipped shipment, so in that case, the shipping date will represent the "all-items cancelation" date.

kennyadsl avatar Jul 07 '23 10:07 kennyadsl

If a shipped shipment has all of its items marked as cancelled, it should remain shipped since the shipped state is supposed to be immutable.

BenMorganIO avatar Jul 07 '23 17:07 BenMorganIO

But I don't see this happening with your code. Maybe I'm missing something?

kennyadsl avatar Jul 08 '23 08:07 kennyadsl

@BenMorganIO let me show that with a quick video (I'm using your branch):

https://github.com/solidusio/solidus/assets/167946/407c0ad6-b20b-4b28-a88c-c4c7c92e561b

kennyadsl avatar Jul 11 '23 08:07 kennyadsl

@kennyadsl I can't understand why someone would cancel all of the items in a shipment after it has been shipped. I think a return would be started if that was the case. However, I want to keep the code so that once a shipment has been shipped, it is effectively immutable and should not transition to canceled.

BenMorganIO avatar Jul 14 '23 19:07 BenMorganIO

I can't understand why someone would cancel all of the items in a shipment after it has been shipped. I think a return would be started if that was the case.

You are right; it's hard to find a use case that resonates with this and the most realistic thing I could think of is having two items in the package (e.g., two glasses), both broken. Probably, you don't want to make a return for broken items, and canceling them would work. Do you think it's something worth taking into account?

kennyadsl avatar Jul 17 '23 08:07 kennyadsl

@kennyadsl I think if we keep shipped shipments retained as shipped, then it shouldn't be an issue. I can see a customer returning all items from a shipment or an admin canceling the items if the shipment was lost or something. Either way, we do have a comment in the code that the shipped state is supposed to be immutable.

BenMorganIO avatar Jul 23 '23 17:07 BenMorganIO