Quantity Discounts with multiple line items

Our products normally include a variety of options yet we give quantity discount normally on total number of same part number ordered.



Client orders 50 product 1 in yellow and 50 product 1 in green…his price is the 100 piece price. I had to code a custom in my current cart for this as well.



My workaround is to provide Assorted as an option for color and a text area entitled color quantity breakdown or something of that nature.



Do I have any other options for handling this?

Is this now available or anyone have a solution? - i.e. we sell bags and give discounts on the total number of bags regardless of colour - 50 blue and 50 pink needs to be the 100 rate price but can't see how to do this. Is this possible with CS-Cart?

You can do give discounts based on Total Products in Cart… if you set it to equal or great than 100, then set a specific price/discount… this would be under Products->Promotions.



Hope that helps

Hi, I had the same issue, this will fix it.



please make the following changes to the fn.cart.php file located in the core directory of your CS-Cart installation:



please replace this part of the code:

$_pdata['price'] = fn_get_product_price($product['product_id'], $product['amount'], $auth);





with this one:

$amount = !empty($product['amount_total']) ? $product['amount_total'] : $product['amount'];

$_pdata['price'] = fn_get_product_price($product['product_id'], $amount, $auth);





and this part of the code:

if (isset($cart['products']) && is_array($cart['products'])) {





with this one:

if (isset($cart['products']) && is_array($cart['products'])) {



$amount_totals = array();

foreach ($cart['products'] as $k => $v) {

if (!empty($amount_totals[$v['product_id']])) {

$amount_totals[$v['product_id']] += $v['amount'];

} else {

$amount_totals[$v['product_id']] = $v['amount'];

}

}

$tracking = db_get_hash_single_array(“SELECT product_id, tracking FROM ?:products WHERE product_id IN (?a)”, array('product_id', 'tracking'), array_keys($amount_totals));

foreach ($cart['products'] as $k => $v) {

unset($cart['products'][$k]['amount_total']);

if (!empty($tracking[$v['product_id']]) && $tracking[$v['product_id']] != 'O') {

$cart['products'][$k]['amount_total'] = $amount_totals[$v['product_id']];

}

}





in the “fn.cart.php” file located in the “core” directory of your CS-Cart installation.

Thank you jazz823 - I am glad to know there may be hope as this is critical functionality - customers expect discounts on the total quantity of a product, regardless of the colours (50 of one colour and 50 of another colour of the same product should both be the 100 price) and without it I cannot move to CS Cart.



I have made the two changes to fn.cart.php, however it is still only giving the quantity discounts based on the quantities of the individual colour options and not the total number of that product. Is there anything else I need to do or have I missed something? - I assume this is working for you - is there a site where I can see this working?



Thanks again,

Richard.

It must be possible to have quantity discounts to work across multiple options of the same product as customers expect discount prices to work regardless of colour or clothing siize etc. - does anyone know how to do this?

[quote name='applied' timestamp='1324201722' post='128013']

It must be possible to have quantity discounts to work across multiple options of the same product as customers expect discount prices to work regardless of colour or clothing siize etc. - does anyone know how to do this?

[/quote]



This addon will solve your problem:

CS-Cart Mix Order Quantity Discount

It is “Inventory - Track with options” which pevents this modification from using the price based on the total quantity of the same product (presumably because when tracking with options it regards each option combination as a different product). This means that I can only have the price based on the total quantity when the options are not being stock controlled - unless there is a fix to be able to enable tracking with options and still base the price on the total number of a products (regardless of options)?

We will be releasing a similar addon in the next few days called Discount Plans. You will be able to define a named discount “plan” and then assign that plan to products. All items in the cart with the same “plan” will have the quantities summed and then the appropriate quantity discount applied per the “plan” definition. There is no restriction on products being variants of each other, only that they have the same plan associated with them. Hence, you can have 3 different products (cable-A, cable-B and cable-C) all associated to discount plan “general quantity”. If cable-A with quantity 10 and cable-B with quantity 10 is in the cart and the plan defines quantities of 10 = 10%, 20 = 20% and 30 = 30% then both cable-A and cable-B will get a 20% discount.



Discounts in the discount tables can be defined as absolute values or percentages (I.e. 3.04 or 10%). Note that these are “discounts”, not prices. So it is “quantity discount” not “quantity pricing” you set in the discount tables.



You will also be able to assign a plan to a category and then (optionally) udpate all products within that category to have that plan applied.



Preliminary documentation can be seen at: http://www.ez-ms.com…count_plans.pdf



Feedback is welcome.

Dear tbirnseth,



Would it be possible to set up one discount plan which restricts the discounts only to products or option variants of products. I understand from your documentation that the way you have implemented this addon would require setting up a different discount plan for each product. To overcome this I am proposing an option within the plan to select: “discount restricted to individual products and their options”.



This way the discount will apply for multiple option combinations of the same product but not across different products (which is how most shoppers would expect it to work). I.e. in most shops the discount is for multiple sizes or colours of the same product but not for different products. Having the facility to select products manually for each discount plan does make it more flexible I suppose (and would be useful for some cross-selling) but also more complex for the “normal” use.



The facility to add products which do not have any options to such a plan would then allow the discounts to be automatically calculated as a percentage. Many of our products (even ones without options) have the same percentage discounts for volume purchases - so when we change the price, this would change the volume prices - Great! But we don't want someone to buy 100 of one product and achieve the 100+ rate on a single purchase of another product - even if it is in the same percentage discount plan.

I must not have been clear. Discount plans are global and a single plan can be assigned to multiple products.

You can create a separate plan and only apply it to the products you want. Discount plans cannot be a applied to a variant unless it is a combination that has it's own product_id.



I'f I'm missunderstanding, please provide a clear step-by-step example so we can walk through it. If you can edit the product info in the admin panel, you can apply a discount plan to it.



The way it is being implemented (change from existing docs) is that if a product has a discount plan assigned to it, it will override any quantity pricing that may exist. All products that use the same plan that are in the customers cart will have their quantities summed together to arrive at the discount to be applied to each product. But unlike pricing, the item price is affected by the discount. I.e. if the discount for 2 products resolves to 10% and one item is $100 and the other is $20 then the total would be $108. I.e. (100-(100*.10) + 20-(20*.10)).



New version should be ready by tomorrow. Testing and rewriting docs now.

And the release page in the 3rd party area for the Discount Plans addon is: Addon: Discount Plans - Third-Party Add-ons - CS-Cart Community Forums

[quote name='jazz823' timestamp='1322572479' post='126925']

Hi, I had the same issue, this will fix it.



please make the following changes to the fn.cart.php file located in the core directory of your CS-Cart installation:



please replace this part of the code:

$_pdata['price'] = fn_get_product_price($product['product_id'], $product['amount'], $auth);





with this one:

$amount = !empty($product['amount_total']) ? $product['amount_total'] : $product['amount'];

$_pdata['price'] = fn_get_product_price($product['product_id'], $amount, $auth);





and this part of the code:

if (isset($cart['products']) && is_array($cart['products'])) {





with this one:

if (isset($cart['products']) && is_array($cart['products'])) {



$amount_totals = array();

foreach ($cart['products'] as $k => $v) {

if (!empty($amount_totals[$v['product_id']])) {

$amount_totals[$v['product_id']] += $v['amount'];

} else {

$amount_totals[$v['product_id']] = $v['amount'];

}

}

$tracking = db_get_hash_single_array(“SELECT product_id, tracking FROM ?:products WHERE product_id IN (?a)”, array('product_id', 'tracking'), array_keys($amount_totals));

foreach ($cart['products'] as $k => $v) {

unset($cart['products'][$k]['amount_total']);

if (!empty($tracking[$v['product_id']]) && $tracking[$v['product_id']] != 'O') {

$cart['products'][$k]['amount_total'] = $amount_totals[$v['product_id']];

}

}





in the “fn.cart.php” file located in the “core” directory of your CS-Cart installation.

[/quote]



Regarding this line of code

if (isset($cart['products']) && is_array($cart['products'])) {



it is in my file 2 times

once on line 1510

and again on line 1585



I am using version 2.2.4



Are you recommending replacing one or both lines of code with the code below?



if (isset($cart['products']) && is_array($cart['products'])) {



$amount_totals = array();

foreach ($cart['products'] as $k => $v) {

if (!empty($amount_totals[$v['product_id']])) {

$amount_totals[$v['product_id']] += $v['amount'];

} else {

$amount_totals[$v['product_id']] = $v['amount'];

}

}

$tracking = db_get_hash_single_array(“SELECT product_id, tracking FROM ?:products WHERE product_id IN (?a)”, array('product_id', 'tracking'), array_keys($amount_totals));

foreach ($cart['products'] as $k => $v) {

unset($cart['products'][$k]['amount_total']);

if (!empty($tracking[$v['product_id']]) && $tracking[$v['product_id']] != 'O') {

$cart['products'][$k]['amount_total'] = $amount_totals[$v['product_id']];

}

}

This addon has no core file changes and it will also show the quantity discount price dynamically.

[url=“CS-Cart Mix Order Quantity Discount”]http://www.cscartrocks.com/cs-cart-mix-order-quantity-discount.html[/url]

In your first post on this addon you stated: “There is no restriction on products being variants of each other” and then later “Discount plans cannot be a applied to a variant unless it is a combination that has it's own product_id”. I don't know what this means - a combination that has it's own product_id? You also mention “if you can edit it in the admin panel” - well it is an option of a product.



I am uncertain if this addon actually does what we expect or not. If it was only applied to a single product - will it calculate the total quantity by adding all variants / options.



To explain with the help of a demo cart - there is a USB modem [url=“http://www.rubblesack.co.uk/en/actiontec-external-usb-home-dsl-modem-bell-south.html”]http://www.rubblesack.co.uk/en/actiontec-external-usb-home-dsl-modem-bell-south.html[/url] which is $18 for one unit and $15 for 10 or more. It comes in white or blue options. The product has “Inventory: Track with options” selected.



I want the total quantity of this product to be used to calculate the price paid - so, for instance 5 white and 5 blue will have the lower price of $15 each. The total quantity of all variants / options needs to be used in calculating the discount for each product.



This I would have expected to be “standard” functionality as with many retail items with options the customer expects discounts to be for the total quantity regardless of, say the colour (for clothing you wouldn't expect to have to buy items the same size or colour to achieve the discounts). This does work with the core code changes in this post until you enable the “Inventory: Track with options” and then it stops working. I don't know if by having “Inventory: Track with options” creates separate product_id for each combination or not (but if it does you cannot see the product_id for each variant) so don't know if this addon will work.



Until there is a way to order multiple colours / options at discount prices based on the total quantity (whilst maintaining the stock control of each colour) we cannot make move to CS-Cart. Everything else about the cart is great, but this is essential functionality which we already use in our existing cart. We actually sell laundry bags and with 10 or more colours for each type of bag we need to have quantity discounts and stock control - current live site with another cart provider is at [url=“Laundry Bags Linen Bags Carry Sacks and Laundry Hampers UK professional laundry bag basket supplies for transporting laundry”]http://www.washingnet.org.uk/laundry_bags.html[/url]. I don't understand why I am struggling so much to get this working in the way I would have expected most online shops that have quantity discounts to require.

the way the addon works is that when an item is added to the cart (for some quantity), all items in the cart are scanned and each item that has the same discount plan associated with it will have the quantities summed together.



This total quantity is then used to determine the discount for all items that are assigned to that plan.



Since the plan defines discounts and not prices, the discount (absolute amount or percentage) is applied to the price of each item based on the total quantity in the cart.



Say you have a discount plan defined as 'planA' (these are discounts, not prices)

quantity 1 == 0

quantity 10 == 1.00

quantity 15 == 1.50



You have 3 products in the cart Bag1, Bag2 and Bag3

Bag2 is a color variant of Bag1 (but bag2 and bag1 share the same product_id).

Bag1 is assigned to 'planA'

Bag3 has no plan



In the cart are 10 Bag1 and 10 Bag2. Hence there are 20 items for product_id xxx. This total is used to determine the discount for both Bag1 and Bag2. The discount becomes 1.50. So the standard price (quantity 1 for usergroup_id zero) of Bag1 and Bag2 are reduced by 1.50.

The cart then multiples the quantity times the price to arrive at item and cart totals.



I believe it will behave as you expect. If not, happy to give you a refund if you're not completely satisfied or work with you to correct any problems with the design.



I think you might be struggling with the difference between quantiy pricing and quantity discounts. In standard cs-cart, quantity pricing is specific to a product. I.e. it is a list of quantities/prices/user_groups. This addon replaces that concept and uses a discount table to determine the “discount” to apply to items that use the same discount plan.



I guess you could think of this more like global discount tables versus quantity pricing.

I believe I understand quantity pricing quantity discounts - your addon is used to define the discount and then it calculates the quantity price based on the unit price and the total quantiy of products in the cart from the same plan (overwriting any quantity pricing for that product). My concern is with variants - it sounds like you are saying it will work with variants, which was my main concern. You earlier stated “Discount plans cannot be a applied to a variant unless it is a combination that has it's own product_id”, which I didn't understand if a colour option has it's own product_id. In your example you show a colour variant sharing the same product_id.



I understand that the quantity of products added to the same plan are used to determine the discount, however I don't want a plan to sum across different products - only sum the options of the same product. So 10 bag1 red and 10bag1 blue will both be at the 20 rate, but if you purchase 10 of a different bag in the same plan then this will be at the 10 rate. I.e. the discount needs to have the facility to be limited to JUST the options of the same product. The addon is more customisable by enabling different products to be discounted together - but this makes it difficult to set-up the same discount structure across all products in the store as I believe it will require a new plan for each product. If the plan had the option to select: “discount restricted to individual products and their options” then you could add multiple products to the same plan to automatically calculate the quantity pricing.

When an item is added to the cart that has variants which have different modifiers (plus/minus amounts) then there is a separate entry in the cart for each item.



ANY ITEM IN THE CART WITH THE SAME PRODUCT ID WILL HAVE THE DISCOUNT PLAN ASSOCIATED WITH THAT PRODUCT ID APPLIED TO IT AND THE QUANTITIES WILL BE SUMMED TOGETHER TO DETERMINE THE QUANTITY TO USE FOR APPLYING THE DISCOUNT TO THE PRICE OF EACH ITEM.



I don't know how many more ways I can say it.



I suggest you simply purchase the addon and try it. If it doesn't meet your needs, simply let me know and I'll refund your money.

Our products normally include a variety of options yet we give quantity discount normally on total number of same part number ordered.

Client orders 50 product 1 in yellow and 50 product 1 in green.....his price is the 100 piece price. I had to code a custom in my current cart for this as well.

My workaround is to provide Assorted as an option for color and a text area entitled color quantity breakdown or something of that nature.

Do I have any other options for handling this?

Mình không trả lời bằng ngôn ngữ Tiếng Anh được, nên sử dụng ngôn ngữ Tiếng Việt nhé. Mình đã áp dụng đoạn code của jazz823 , có thay đổi 1 chút và đã thà nh công :

Phiên bản : cs-cart 4.2.4

Đường dẫn : public_html/app/functions/fn.cart.php

please make the following changes to the fn.cart.php file located in the core directory of your CS-Cart installation:

please replace this part of the code:
$_pdata['price'] = fn_get_product_price($product['product_id'], $product['amount'], $auth);

with this one:
$amount = !empty($product['amount_total']) ? $product['amount_total'] : $product['amount'];
$_pdata['price'] = fn_get_product_price($product['product_id'], $amount, $auth);


and this part of the code:
if (isset($cart['products']) && is_array($cart['products'])) {

foreach ($cart['products'] as $cart_id => $product) {

with this one:
if (isset($cart['products']) && is_array($cart['products'])) {
$amount_totals = array();
foreach ($cart['products'] as $k => $v) {
if (!empty($amount_totals[$v['product_id']])) {
$amount_totals[$v['product_id']] += $v['amount'];
} else {
$amount_totals[$v['product_id']] = $v['amount'];
}
}
$tracking = db_get_hash_single_array("SELECT product_id, tracking FROM ?:products WHERE product_id IN (?a)", array('product_id', 'tracking'), array_keys($amount_totals));
foreach ($cart['products'] as $k => $v) {
unset($cart['products'][$k]['amount_total']);
if (!empty($tracking[$v['product_id']]) && $tracking[$v['product_id']] != 'O') {
$cart['products'][$k]['amount_total'] = $amount_totals[$v['product_id']];
}
}

foreach ($cart['products'] as $cart_id => $product) {

and this part of the code:

if (isset($cart['products']) && is_array($cart['products'])) {

$amount_totals = array();
if (Registry::get('settings.General.disregard_options_for_discounts') == 'Y') {
foreach ($cart['products'] as $k => $v) {
if (!empty($amount_totals[$v['product_id']])) {
$amount_totals[$v['product_id']] += $v['amount'];
} else {
$amount_totals[$v['product_id']] = $v['amount'];
}
}
}
with this one:
if (isset($cart['products']) && is_array($cart['products'])) {
$amount_totals = array();
foreach ($cart['products'] as $k => $v) {
if (!empty($amount_totals[$v['product_id']])) {
$amount_totals[$v['product_id']] += $v['amount'];
} else {
$amount_totals[$v['product_id']] = $v['amount'];
}
}
$tracking = db_get_hash_single_array("SELECT product_id, tracking FROM ?:products WHERE product_id IN (?a)", array('product_id', 'tracking'), array_keys($amount_totals));
foreach ($cart['products'] as $k => $v) {
unset($cart['products'][$k]['amount_total']);
if (!empty($tracking[$v['product_id']]) && $tracking[$v['product_id']] != 'O') {
$cart['products'][$k]['amount_total'] = $amount_totals[$v['product_id']];
}
}
P/S : ở đây, Mình đã sử dụng đoạn code của jazz823 2 lần ở 2 vị trí trong file "fn.cart.php".