I can share what I did, but you'll still have to modify it for your scenario.
In both Admin/Products/Kits/AddKitProducts.aspx and Admin/Products/Kits/EditKitProduct.aspx, added the following right under the KitQuantity row:
Code: Select all
<tr>
<th>
<cb:ToolTipLabel ID="ParentQuantityLabel" runat="server" Text="Parent quantity grouping:" AssociatedControlID="ParentQuantity" ToolTip="If parent quantities > 1 should only get a fixed quantity of this product, enter that parent quantity here. For example, a 10 here and a quantity 1 above would mean that any quantity from 1-10 of the parent product will add 1 of this product. Leave at 1 to add the above quantity of this product for every parent product"></cb:ToolTipLabel>
</th>
<td>
<asp:TextBox ID="ParentQuantity" runat="server" Columns="2" MaxLength="3" Text="1"></asp:TextBox>
</td>
</tr>
In Admin/Products/Kits/AddKitProducts.aspx.cs, added the following in FinishButton_Click, at the end of the "if (quantity > 0)..." section:
Code: Select all
if (quantity > 0)
{
// existing code here....
TextBox ParentQuantity = (TextBox)ri.FindControl("ParentQuantity");
int parentQuantity = AlwaysConvert.ToInt(ParentQuantity.Text);
if (parentQuantity == 0) parentQuantity = 1;
AbleCommerce.Code.CustomFieldHelper.SetInt(kitProduct, "ac_KitProducts", "ParentQuantity", parentQuantity);
ParentQuantity.Text = parentQuantity.ToString();
}
In Admin/Products/Kits/EditKitProduct.aspx.cs, added the following at the end of Page_Init:
Code: Select all
int? parentQuantity = AbleCommerce.Code.CustomFieldHelper.GetInt(_KitProduct, "ac_KitProducts", "ParentQuantity");
if (!parentQuantity.HasValue) parentQuantity = 1;
ParentQuantity.Text = parentQuantity.ToString();
In Admin/Products/Kits/EditKitProduct.aspx.cs, added the following in SaveButton_Click, at the end of the "if (quantity > 0)..." section:
Code: Select all
if (quantity > 0)
{
// existing code here....
int parentQuantity = AlwaysConvert.ToInt(ParentQuantity.Text);
if (parentQuantity == 0) parentQuantity = 1;
AbleCommerce.Code.CustomFieldHelper.SetInt(_KitProduct, "ac_KitProducts", "ParentQuantity", parentQuantity);
ParentQuantity.Text = parentQuantity.ToString();
}
In CommerceBuilder/Products/KitProduct.cs, added the following to the DisplayName field, right before the "return displayName;" statement:
Code: Select all
NHibernate.ICriteria quantityGroupingCriteria = NHibernateHelper.CreateCriteria<CommerceBuilder.Stores.CustomField>()
.Add(NHibernate.Criterion.Restrictions.Eq("Store.Id", CommerceBuilder.Common.AbleContext.Current.StoreId) &&
NHibernate.Criterion.Restrictions.Eq("TableName", "ac_KitProducts") &&
NHibernate.Criterion.Restrictions.Eq("ForeignKeyId", this.Id) &&
NHibernate.Criterion.Restrictions.Eq("FieldName", "ParentQuantity"));
System.Collections.Generic.IList<CommerceBuilder.Stores.CustomField> kitProductFields = CommerceBuilder.Stores.CustomFieldDataSource.LoadForCriteria(quantityGroupingCriteria);
if (kitProductFields.Count > 0)
{
int parentQuantity = AlwaysConvert.ToInt(kitProductFields[0].FieldValue);
if (parentQuantity > 1)
{
displayName = displayName + " (for up to " + parentQuantity.ToString() + " parts)";
}
}
In CommerceBuilder/Products/KitProductRepository.cs, added the following to override BeforeDelete:
Code: Select all
/// <inheritdoc />
public override void BeforeDelete(object entity)
{
NHibernate.ICriteria quantityGroupingCriteria = NHibernateHelper.CreateCriteria<CommerceBuilder.Stores.CustomField>()
.Add(NHibernate.Criterion.Restrictions.Eq("Store.Id", CommerceBuilder.Common.AbleContext.Current.StoreId) &&
NHibernate.Criterion.Restrictions.Eq("TableName", "ac_KitProducts") &&
NHibernate.Criterion.Restrictions.Eq("ForeignKeyId", ((KitProduct)entity).Id) &&
NHibernate.Criterion.Restrictions.Eq("FieldName", "ParentQuantity"));
System.Collections.Generic.IList<CommerceBuilder.Stores.CustomField> kitProductFields = CommerceBuilder.Stores.CustomFieldDataSource.LoadForCriteria(quantityGroupingCriteria);
foreach (CommerceBuilder.Stores.CustomField oneField in kitProductFields)
{
oneField.Delete();
}
}
In CommerceBuilder/Services/Checkout/BasketService.cs, in the RecalculateItems method, find:
Code: Select all
childItem.Quantity = (short)(kitProduct.Quantity * basketItem.Quantity);
and replace it with:
Code: Select all
decimal parentQuantity = GetCustomDecimal(kitProduct, "ac_KitProducts", "ParentQuantity");
if (parentQuantity < 1.0M) parentQuantity = 1.0M;
parentQuantity = Math.Ceiling((decimal)basketItem.Quantity / parentQuantity);
childItem.Quantity = (short)(kitProduct.Quantity * (short)parentQuantity);
In CommerceBuilder/Services/Checkout/CheckoutService.cs, in the GenerateKitOrderItems method, find:
Code: Select all
item.Quantity = (short)(kp.Quantity * basketItem.Quantity);
and replace it with:
Code: Select all
string parentQuantityString = GetCustomString(kp, "ac_KitProducts", "ParentQuantity");
decimal parentQuantity = string.IsNullOrEmpty(parentQuantityString) ? 1.0M : AlwaysConvert.ToDecimal(parentQuantityString);
if (parentQuantity < 1.0M) parentQuantity = 1.0M;
parentQuantity = Math.Ceiling((decimal)basketItem.Quantity / parentQuantity);
item.Quantity = (short)(kp.Quantity * (short)parentQuantity);
I'm not sure where I was in the process of learning C#, ASP.NET, and NHibernate when I wrote that code, so I can't vouch for how efficient or "correct" the code is, other than that it seems to be working fine

. Also, you may have to add some "using" statements to some of those files to include the required namespaces.