Hello,
SHORT INTRODUCTION
I was never satisfied with the native behaviour of "delayed shipping" feature in PS 1.6 - it's very helpful but it just doesn't work properly and I wanted to improve it. I have managed to add JSON support and changed its behaviour a little bit. Previously I have modified the behaviour of AVAILABILITY column (which I also described here) in shopping-cart-product-line.tpl, so it now shows 'STOCK quantity' and 'BACKORDER quantity' (or ON REQUEST in my case, since I'm using module which disables COD payment for orders with BACKORDER products and leaves only pre-payment methods).
Now, we have a several cases regarding the "delayed shipping" feature, which we have to investigate:
1) All products in cart have no stock (stock quantity <= 0) in the cart -> delayed shipping not appearing (in native PS it was appearing which was wrong - there is nothing to split here) = works OK -> https://streamable.com/guvfv
2) All products in cart have positive stock (stock quantity > 0) -> delayed shipping appears when the cart quantity exceeds stock quantity - works OK -> https://streamable.com/3v7kh
3) Products in cart have both positive stock (stock quantity > 0) and no stock (stock quantity <= 0).
- I'm deleting out_of_stock products form the cart - works OK -> https://streamable.com/r3ipf
- I'm deleting in_stock products form the cart - works OK -> https://streamable.com/j3fdf
CODE MODIFICATIONS
File: \classes\Cart.php -> I have added 2 functions, which are counting in_stock nad out_of_stock products in the cart
public function countOOSProducts() { $product_out_of_stock = 0; foreach ($this->getProducts() as $product) { if ((int)$product['quantity_available'] <= 0 && (!$ignore_virtual || !$product['is_virtual'])) { $product_out_of_stock++; } } return $product_out_of_stock; } public function countISProducts() { $product_in_stock = 0; foreach ($this->getProducts() as $product) { if ((int)$product['quantity_available'] > 0 && (!$ignore_virtual || !$product['is_virtual'])) { $product_in_stock++; } } return $product_in_stock; }
I have added new variables returned by these functions to summary array() to pass them into front files, so the new array() looks like this:
$summary = array( 'delivery' => $delivery, 'delivery_state' => State::getNameById($delivery->id_state), 'invoice' => $invoice, 'invoice_state' => State::getNameById($invoice->id_state), 'formattedAddresses' => $formatted_addresses, 'products' => array_values($products), 'gift_products' => $gift_products, 'discounts' => array_values($cart_rules), 'is_virtual_cart' => (int)$this->isVirtualCart(), 'product_in_stock' => $this->countISProducts();, 'product_out_of_stock' => $this->countOOSProducts();, 'total_discounts' => $total_discounts, 'total_discounts_tax_exc' => $total_discounts_tax_exc, 'total_wrapping' => $this->getOrderTotal(true, Cart::ONLY_WRAPPING), 'total_wrapping_tax_exc' => $this->getOrderTotal(false, Cart::ONLY_WRAPPING), 'total_shipping' => $total_shipping, 'total_shipping_tax_exc' => $total_shipping_tax_exc, 'total_products_wt' => $total_products_wt, 'total_products' => $total_products, 'total_price' => $base_total_tax_inc, 'total_tax' => $total_tax, 'total_price_without_tax' => $base_total_tax_exc, 'is_multi_address_delivery' => $this->isMultiAddressDelivery() || ((int)Tools::getValue('multi-shipping') == 1), 'free_ship' =>!$total_shipping && !count($this->getDeliveryAddressesWithoutCarriers(true, $errors)), 'carrier' => new Carrier($this->id_carrier, $id_lang), );
File: \themes\your_theme\js\cart-summary.js -> I have modified function updateCartSummary(json) a little bit by adding following code:
// Definition of variables, which will store the quantity exceeding 'stock quantity' in shopping cart 886: var OosProducts = 0; 887: var OosProductsTotal = 0; // Definition of the variable storing text, which is apearing while product is out_of_stock and ordering is allowed 921: var available_later = product_list[i].available_later; // Display quantity exceeding stock quantity in shopping cart 991: OosProducts = parseInt(product_list[i].quantity) - parseInt(product_list[i].quantity_available); 992: if (OosProducts > 0) { 993: $('#outofstock_availability_' + key_for_blockcart).html(available_later + ' (' + quantity + ': ' + OosProducts + ')'); 994: $('#outofstock_availability_' + key_for_blockcart).show(); 995: } 996: else { 997: $('#outofstock_availability_' + key_for_blockcart).hide(); 998: } 999: OosProductsTotal += (parseInt(product_list[i].quantity) - parseInt(product_list[i].quantity_available)); // 'delayed shipping' behaviour 1006: if (parseInt(product_list[i].quantity_available) > 0) { 1007: if ((OosProducts-OosProductsTotal > 0 || OosProducts > 0) && (OosProducts == OosProductsTotal) || (OosProducts-OosProductsTotal < 0) || OosProducts > 0 && (OosProducts !== OosProductsTotal)) { 1008: $('.allow_seperated_package').show(); 1009: $('.allow_seperated_package').css({'color':'white', 'background-color':'orange', 'padding':'10px', 'display':'inline-block'}); 1010: $('.allow_seperated_package2').text('(' + OosProducts + ') ' + '- (' + OosProductsTotal + ') -> ' + '(' + (OosProducts-OosProductsTotal) + ')'); 1011: } else { 1012: $('.allow_seperated_package').hide(); 1013: $('.allow_seperated_package2').text('(ELSE -> (' + OosProducts + ') ' + '- (' + OosProductsTotal + ') -> ' + '(' + (OosProducts-OosProductsTotal) + ')'); 1014: } 1015: 1016: } else { 1017: $('.allow_seperated_package').hide(); 1018: $('.allow_seperated_package2').text('(OUT -> (' + OosProducts + ') ' + '- (' + OosProductsTotal + ') -> ' + '(' + (OosProducts-OosProductsTotal) + ')'); 1019: }
File: \themes\your_theme\shopping-cart.tpl -> I have modified the "delayed shipping" code:
638: <p class="allow_seperated_package" {if ($show_option_allow_separate_package && {$product_in_stock} > 0)}style="background: orange; padding: 10px; display: inline-block;"{else}style="display: none;"{/if}> 639: <input type="checkbox" name="allow_seperated_package" id="allow_seperated_package" {if $cart->allow_seperated_package}checked="checked"{/if} autocomplete="off"/ > 640: <label for="allow_seperated_package" class="checkbox inline"> 641: {l s='Send available products first'} 642: </label> 643: </p>
File: \themes\your_theme\shopping-cart-product-line.tpl - I have changed a behaviour in shopping cart AVAILIBILITY column here by modifying the native code as following:
25: {if $product.quantity_available <= 0} 26: {if isset($product.allow_oosp) && $product.allow_oosp} 27: {if isset($product.available_later) && $product.available_later} 28: {$product.available_later}{else}{l s='In Stock'} 29: {/if} 30: {else} 31: {l s='Out of stock'} 32: {/if} 33: {else} 34: {if isset($product.available_now) && $product.available_now} 35: {if $product.cart_quantity-$product.quantity_available <= 0} 36: {$product.available_now} ({l s='Quantity'}: {$product.quantity_available}) <br /><br /> 37: <span id="outofstock_availability_{$product.id_product}_{$product.id_product_attribute}_{if $quantityDisplayed > 0}_nocustom{/if}_{$product.id_address_delivery|intval}{if !empty($product.gift)}_gift{/if}" class="label-warning"> </span> 38: {else} 39: {$product.available_now} ({l s='Quantity'}: {$product.quantity_available}) <br /><br /> 40: <span id="outofstock_availability_{$product.id_product}_{$product.id_product_attribute}{if $quantityDisplayed > 0}_nocustom{/if}_{$product.id_address_delivery|intval}{if !empty($product.gift)}_gift{/if}" class="label-warning">{$product.available_later} ({l s='Quantity'}: {$product.cart_quantity-$product.quantity_available})</span> 41: {/if} 42: {else} 43: {if $product.cart_quantity-$product.quantity_available <= 0} 44: {l s='In Stock'} ({l s='Quantity'}: {$product.quantity_available}) <br /><br /> 45: <span id="outofstock_availability_{$product.id_product}_{$product.id_product_attribute}{if $quantityDisplayed > 0}_nocustom{/if}_{$product.id_address_delivery|intval}{if !empty($product.gift)}_gift{/if}" class="label-warning"> </span> 46: {else} 47: {l s='In Stock'} ({l s='Quantity'}: {$product.quantity_available}) <br /><br /> 48: <span id="outofstock_availability_{$product.id_product}_{$product.id_product_attribute}{if $quantityDisplayed > 0}_nocustom{/if}_{$product.id_address_delivery|intval}{if !empty($product.gift)}_gift{/if}" class="label-warning">{$product.available_later} ({l s='Quantity'}: {$product.cart_quantity-$product.quantity_available})</span> 49: {/if} 50: {/if} 51: {/if}
CONCLUSIONS
If you use modules displaying products in cart summary (shopping-cart.tpl) hooks (like crossseling) there is also a need to force page refresh after product "add to cart" action to make it work properly, since PS 1.6 does not support ajax for this action on cart summary page.
And basically that's it. Maybe someone finds it helpful in his struggle with PrestaShop. If anyone have any suggestions I would bevery grateful.
Best regards,
Radoslaw