Cart Shipping Lost When Registering (Commerce 11.8.2)

Vote:
 

We have a process where users can complete our basket process anonymously. During this process a user can fill in a billing and delivery address with the following code

cart = cart ?? CommerceHelper.Service.GetCart(basketType);

if (cart != null)
{
   var shipment = cart.GetFirstShipment();
   if (shipment == null)
   {
      shipment = cart.CreateShipment();
      cart.AddShipment(shipment);
   }

var address = OrderGroupRepository.Service.CreateOrderAddress(cart);
AddressConverterService.Service.MapOrderAddress(address, addressData);
shipment.ShippingAddress = address;
OrderRepository.Service.Save(cart);

With the address convert code just mapping the model between ours and the underlying commerce mapping model

/// <inheritdoc />
public void MapOrderAddress(IOrderAddress address, AddressData addressData)
{
    var name = $"{addressData.Building}, {addressData.Address}, {addressData.Postcode}";

    address.Id = name;
    address.Email = addressData.Email;
    address.FirstName = addressData.FirstName;
    address.LastName = addressData.LastName;
    address.DaytimePhoneNumber = addressData.Phone;
    address.Line1 = addressData.Building;
    address.Line2 = addressData.Address;
    address.PostalCode = addressData.Postcode;
    address.CountryName = addressData.CountryName;
    address.CountryCode = addressData.CountryCode;
    address.City = addressData.Town;
    address.RegionName = addressData.County;
}

If the user then registers an account (Using starndard ASP.NET Indentity and Commerce code) the shipment.ShippingAddress is then coming back as null.

I imagine it's something to do with maybe the Cart merging but I've been unable not narrow it down. Does anyone have any knowledge around this issue?

Thanks,

Scott

#203673
May 02, 2019 12:44
Vote:
 

While I am not entirely sure this sounds like something we fixed in a later version. And you know I love recommending people to upgrade.

#203683
May 02, 2019 18:03
Vote:
 
#203711
Edited, May 03, 2019 15:03
Vote:
 

Thanks Quan, yeah I 100% agree on upgrade policies. We usually put one in place for regular updates but we we thought we were hitting the near go Live so had to put in an upgrade freeze otherwise changes would have too wide reaching impact on a lot of our custom tax calculators and a few other bits.

After go Live we'll be looking at upgrading, do you know if there's a work around (e.g. replacing an implementation in the meantime?)

Thanks, Scott

#203776
May 07, 2019 10:47
Vote:
 

Technically you can implement your own IProfileMigrator (or just intercept it) to make sure the shipments are migrated properly for carts. However it is not trivial to get right (not underestimating you, just stating the fact) 

#203777
May 07, 2019 10:54
Vote:
 

Thanks, yeah I've decompiled and looked at this before and it didn't seem an easy task. Would this particular issue just be resolved if I took the new code for the Profile Migrator class? 

#203780
May 07, 2019 11:14
Vote:
 

Nobody can say that if it works for sure :) 

#203781
May 07, 2019 11:19
Vote:
 

haha well I'll give it a try and see what happens :p Thanks Quan

#203783
May 07, 2019 11:30
Vote:
 

Managed to get it working, although oddly version 12.0.0 that I used as a comparison didn't work for me. The code that was added in this version was a line in the Migrate carts when looping through them MigrateContactAddresses as below

    this.MergeForms(sourceCart, cart2);
    this.MergeShipments(cart2);
    this._orderRepository.Save((IOrderGroup) cart2);
    this._orderRepository.Delete(sourceCart.OrderLink);
    this.MigrateContactAddresses(customerContact, cart2);

Calling

    protected virtual void MigrateContactAddresses(CustomerContact customerContact, ICart cart)
    {
      IShipment firstShipment = cart.GetFirstShipment();
      if (firstShipment?.ShippingAddress == null)
        return;
      IOrderAddress shippingAddress = firstShipment.ShippingAddress;
      string addressName = shippingAddress.LastName + " " + shippingAddress.LastName;
      if (customerContact.ContactAddresses.Any<CustomerAddress>((Func<CustomerAddress, bool>) (a => a.Name == addressName)))
        return;
      CustomerAddress instance = CustomerAddress.CreateInstance();
      instance.Name = addressName;
      instance.Line1 = shippingAddress.Line1;
      instance.Line2 = shippingAddress.Line2;
      instance.FirstName = shippingAddress.FirstName;
      instance.LastName = shippingAddress.LastName;
      instance.Email = shippingAddress.Email;
      instance.PostalCode = shippingAddress.PostalCode;
      instance.City = shippingAddress.City;
      instance.CountryCode = shippingAddress.CountryCode;
      instance.CountryName = shippingAddress.CountryName;
      instance.RegionCode = shippingAddress.RegionCode;
      instance.RegionName = shippingAddress.RegionName;
      customerContact.AddContactAddress(instance);
      customerContact.SaveChanges();
    }

This seems to be more setting an a custom address from in the contact address from what I could see. The delivery address that you can in in sourceCart in the first code was still being lost. So I implemented my own code before the Save/Delete in the first code

        protected virtual void MigrateContactAddresses(ICart sourceCart, ICart destinationCart)
        {
            var sourceShipment = sourceCart.GetFirstShipment();

            if (sourceShipment?.ShippingAddress != null)
            {
                var shipment = destinationCart.GetFirstShipment();
                if (shipment == null)
                {
                    shipment = destinationCart.CreateShipment();
                }
                shipment.ShippingAddress = sourceShipment.ShippingAddress;
            }
        }

And this is now fixing my problem. I would say it's a shame the CartMigrator isn't driven off an Interface with Overridable methods as it means the annoyance of having to create the ProfileMigrator as well when I just wanted to handling the cart migration.

#203794
May 07, 2019 13:25
Vote:
 

Actually I see there was an additon to the MergeForms as well with 

            IOrderAddress shippingAddress = shipment.ShippingAddress;
            orderForm2.Shipments.Add(shipment);
            shipment.ShippingAddress = shippingAddress;

That's probably the code I'm missing that makes it work lol. Thanks for the help

#203795
May 07, 2019 13:31
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.