Need:  The project requires every item ordered from the AbleCommerce 7 storefront to be assigned it’s own shipment.  The reason is each item is made separately and must ship separately.  Even if multiple quantities of the same item are purchased, each unit of 1 must be by itself on a separate shipment.

 

Justification: Existing AC7 code will automatically split basket items up into separate shipments based on the WarehouseId value assigned to each product in the basket.  However this does not split up multiple quantities of the same item.  Even if an item is set as “Ships Separately” on the Edit Product page, AC7 will not break each quantity of the multi-quantity item into separate shipments.  Thus custom code is required.

 

Solution:  Create a new helper class in /App_Code/.  I called mine AbleModsHelper.Basket.cs.  Put the following code into the file and call the routine in the basket initialization area of OnePageCheckout.ascx.cs.  You’ll probably want to comment out the original Basket.Package() code so AbleCommerce libraries don’t mess up your shipments.

 

/// <summary>

/// Builds a shipment for each quantity of each product in the supplied basket

/// </summary>

/// <param name="_Basket">Basket to which shipments will be assigned</param>

public static void MakeBasketShipments(Basket _Basket)

{

    // Reset basket item shipment assignments 

    foreach (BasketItem _BasketItem in _Basket.Items)

    {

        _BasketItem.BasketShipmentId = 0;

        _BasketItem.Save();

    }

 

    // remove any shipments after shipment[0]

    if (_Basket.Shipments.Count > 1)

        for (int x = 1; x < _Basket.Shipments.Count; x++)

            _Basket.Shipments[x].Delete();

 

    // loop through basket items and make new shipments for each item and quantity ordered

    //BasketItemCollection _NewItems = new BasketItemCollection();

    int _ItemCount = _Basket.Items.Count;

    for (int _Count = 0; _Count < _ItemCount; _Count++)

    {

        BasketItem _BasketItem = _Basket.Items[_Count];

        // skip anything that's not a product or is already Qty 1

        if (_BasketItem.OrderItemType != OrderItemType.Product | _BasketItem.Quantity <= 1)

            continue;

 

        // we've got an item with multiple quantity - split it out using the original basketitem

        // record as a template.

        // first though, we must reset the new "master" product to qty 1

        int _LoopQty = _BasketItem.Quantity - 1;

        _BasketItem.Quantity = 1;

        _BasketItem.Save();

 

        // loop through remaining quantity of this item

        for (int x = 0; x < _LoopQty; x++)

        {

            // clone the original basket item

            BasketItem _NewItem = _BasketItem.Clone();

 

            // set it's quantity and basketid

            _NewItem.Quantity = 1;

            _NewItem.BasketId = _Basket.BasketId;

 

            // save the duplicate basketitem 

            _NewItem.Save();

 

            // clone any basket inputs from the original basket item

            foreach (BasketItemInput _BasketInput in _BasketItem.Inputs)

            {

                BasketItemInput _NewInput = new BasketItemInput();

                _NewInput.BasketItemId = _NewItem.BasketItemId;

                _NewInput.InputFieldId = _BasketInput.InputFieldId;

                _NewInput.InputValue = _BasketInput.InputValue;

                _NewInput.Save();

            }

 

            // add new item it to the basket

            _Basket.Items.Add(_NewItem);

            _Basket.Save();

        }

 

    }

 

    // clear out all shipments for this basket

    _Basket.Shipments.DeleteAll();

 

    // Sort the basket so the items are grouped together by name

    BasketItemCollection _BasketItems = _Basket.Items;

    _BasketItems.Sort("Name");

 

    // We have all basket items broken into separate lines

    // Create unique shipment for each basket item that doesn't already have a shipment assigned to it

    foreach (BasketItem _BasketItem in _BasketItems)

    {

        // skip basket item if not a product

        if (_BasketItem.OrderItemType != OrderItemType.Product)

            continue;

 

        // make new shipment

        BasketShipment _Shipment = new BasketShipment();

        _Shipment.BasketId = _Basket.BasketId;

        _Shipment.WarehouseId = _BasketItem.Product.WarehouseId;

        _Shipment.AddressId = Token.Instance.User.PrimaryAddress.AddressId;

        _Shipment.Save();

 

        // add new shipment to basket

        _Basket.Shipments.Add(_Shipment);

 

        // assign this basket item to the new shipment

        _BasketItem.BasketShipmentId = _Shipment.BasketShipmentId;

        _BasketItem.Save();

 

        //// reset the parentitemid value since now this item is its own basket item record

        _BasketItem.ParentItemId = _BasketItem.BasketItemId;

        _BasketItem.Save();

 

    }

 

    // save the basket

    _Basket.Save();

 

}