Adding Custom Charge
Adding Custom Charge
We are trying to use variants or kitting to add a preset charge that is static (ie. it is a charge that will not change with order qty). The goal is specifically for our private label sauces, allowing us to add an artwork fee to new custom labels. This will not be based on the qty of a sauce that the customer orders, and will only be assigned to one variant. It is straight forward adding a per unit add-on, but how can we add a flat fee when a specific selection is made? This way, if a customer wants a generic label, or already has custom artwork on file, they will not have the charge added.
We have tried using a separate 'product' that must be added if custom work is involved, but, of course, nobody adds that by choice- hoping that we will just let it slide through. That creates the hassle of calling the customer, adding to their order, and getting authorization for the charge. It is much easier, and more professional, to have it done seamlessly based on their selection.
We have tried using a separate 'product' that must be added if custom work is involved, but, of course, nobody adds that by choice- hoping that we will just let it slide through. That creates the hassle of calling the customer, adding to their order, and getting authorization for the charge. It is much easier, and more professional, to have it done seamlessly based on their selection.
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot
Brewhaus (America) Inc.
Hot Sauce Depot
Re: Adding Custom Charge
Not sure but what about placing some code to add basket item of type OrderItemType.Charge when some option is selected. The complicated part of this will be to ensure to add/remove charge item if basket changes.
Re: Adding Custom Charge
Variants are the perfect option, unfortunately the extra charge will be added for each bottle, not as a one-time charge. The advantage is that the charge would also be removed if the product is removed from the cart. Kitting would do the same thing, but has the same problem- it is added once for each bottle purchased. I expect that it would require some in-depth coding to create a variant or kit item that only adds a flat rate once.
One thought- is it possible to add a 'handling fee' to a product? If so, then maybe the handling fee could be added only if a specific variant or kit item was selected.
One thought- is it possible to add a 'handling fee' to a product? If so, then maybe the handling fee could be added only if a specific variant or kit item was selected.
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot
Brewhaus (America) Inc.
Hot Sauce Depot
-
- Commodore (COMO)
- Posts: 436
- Joined: Tue May 07, 2013 1:59 pm
Re: Adding Custom Charge
I have a similar requirement - I need to add quantity 1 of product B for every 1-10 quantity of product A (so quantity 1-10 A = 1 B, quantity 11-20 A = 2 B, etc.). I implemented it using kits and an entry in the ac_CustomFields table related to the ac_KitProducts table.
I had to modify the following site pages:
Admin/Products/Kits/AddKitProduct
Admin/Products/Kits/EditKitProduct
and the following source code files:
CommerceBuilder/Products/KitProduct.cs
CommerceBuilder/Products/KitProductRepository.cs
CommerceBuilder/Services/Checkout/CheckoutService.cs
CommerceBuilder/Services/Checkout/BasketService.cs
If you want, I can try to dig up what the actual changes were. Note that is on R5, not using single page checkout.
EDIT: Your changes would probably be simpler than mine, because you don't care about the actual quantity of product A, you just want only one of Product B. So you'd only need a "true/false" flag for your kit that means "only add one/standard behavior". You still might need to change the same files, but the changes might be less code.
EDIT 2: Corrected site and source code file names.
I had to modify the following site pages:
Admin/Products/Kits/AddKitProduct
Admin/Products/Kits/EditKitProduct
and the following source code files:
CommerceBuilder/Products/KitProduct.cs
CommerceBuilder/Products/KitProductRepository.cs
CommerceBuilder/Services/Checkout/CheckoutService.cs
CommerceBuilder/Services/Checkout/BasketService.cs
If you want, I can try to dig up what the actual changes were. Note that is on R5, not using single page checkout.
EDIT: Your changes would probably be simpler than mine, because you don't care about the actual quantity of product A, you just want only one of Product B. So you'd only need a "true/false" flag for your kit that means "only add one/standard behavior". You still might need to change the same files, but the changes might be less code.
EDIT 2: Corrected site and source code file names.
Last edited by jguengerich on Fri Jul 17, 2015 8:10 am, edited 2 times in total.
Jay
Re: Adding Custom Charge
If you are able to dig up the information / method that you used without too much trouble, and don't mind sharing it, that would be very much appreciated. 

Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot
Brewhaus (America) Inc.
Hot Sauce Depot
-
- Commodore (COMO)
- Posts: 436
- Joined: Tue May 07, 2013 1:59 pm
Re: Adding Custom Charge
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:
In Admin/Products/Kits/AddKitProducts.aspx.cs, added the following in FinishButton_Click, at the end of the "if (quantity > 0)..." section:
In Admin/Products/Kits/EditKitProduct.aspx.cs, added the following at the end of Page_Init:
In Admin/Products/Kits/EditKitProduct.aspx.cs, added the following in SaveButton_Click, at the end of the "if (quantity > 0)..." section:
In CommerceBuilder/Products/KitProduct.cs, added the following to the DisplayName field, right before the "return displayName;" statement:
In CommerceBuilder/Products/KitProductRepository.cs, added the following to override BeforeDelete:
In CommerceBuilder/Services/Checkout/BasketService.cs, in the RecalculateItems method, find:
and replace it with:
In CommerceBuilder/Services/Checkout/CheckoutService.cs, in the GenerateKitOrderItems method, find:
and replace it with:
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.
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>
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();
}
Code: Select all
int? parentQuantity = AbleCommerce.Code.CustomFieldHelper.GetInt(_KitProduct, "ac_KitProducts", "ParentQuantity");
if (!parentQuantity.HasValue) parentQuantity = 1;
ParentQuantity.Text = parentQuantity.ToString();
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();
}
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)";
}
}
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();
}
}
Code: Select all
childItem.Quantity = (short)(kitProduct.Quantity * basketItem.Quantity);
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);
Code: Select all
item.Quantity = (short)(kp.Quantity * basketItem.Quantity);
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);

Jay
Re: Adding Custom Charge
Thank you very much. I had hoped to look at this over the weekend, but time got away from me. Hopefully I can get through it this week and test it on our DEV site.
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot
Brewhaus (America) Inc.
Hot Sauce Depot