Commerce Version 13.31.0
I'd like to be able to set the value of a MetaField in the Order Management UI even after a product has expired. However, when attempting to update a MetaField value I get the message
The product <Code> is not available in store and was removed from your cart.
The product is not actually removed, but the field update does not succeed.
Reviewing the decompiled code for the Order management api, it seems that the MetaFieldControllerBase method UpdateOrderGroupMetaField runs the OrderValidationService.ValidateOrder(IOrderGroup) method on the order before saving it in the OrderRepository. As part of this, it runs the IIOrderGroupExtensions.ValidateOrRemoveLineItems routine which ensures that products are published.
However, the behavior I'd like (being able to update an order after it was create, depsite the products for its line items being expired) seems reasonable. Do I need to customize and register a new implementation of OrderValidationService to get this to work?
That is how out of the box Line Item Validator works. Optimizely Order management UI uses the same validator, which would throw errors if you have expired product. If your customer's business requirement for line item validation is different from what is in the out of the box, you always override the DefaultLineItemValidator implementing ILineItemValidator. We have done the same for most of our Optimizely commerce implementation.
In you case, you want to allow expired products to stay in cart/ purchase order. In our case, we did not want to remove line item from the cart if there is error, but rather show error message to the end user and let the user makes the adjustment to the cart to proceed to checkout.
Hope that helps.
What you are saying makes sense. That's a very nice feature to notify a user when an expired product is in their cart.
Our case is slightly different. We don't want to allow expired products in user's carts. But, I don't see the utility of validating product expiration in an order. If we want to mark an order fulfilled, it doesn't really matter if the product has expired. We should still be able to edit the order's properties.
In order to get different behavior betwen carts and order, I thought we might need to override OrderValidationService. But, looking more closely after reading your comment, I see we can get the parent order group from the ILineItem in DefaultLineItemValidator.Validate and examine its type:
I still think that the default behavior is a bug: modifying order MetaField values shouldn't be dependent on the published status of the products. But, I think I see how to work around it now.
Thanks for your help.