Jump to content

"Delayed shipping" improvement PS1.6 (added JSON support etc.)


Recommended Posts

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).


CODE MODIFICATIONS

File: \classes\Cart.php -> I have added 2 functions, which are counting in_stock nad out_of_stock (backorder) 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(),
	    // adding 2 new variables
            '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 variable storing the each line 'backorder quantity' in shopping cart
886:   var OosProducts = 0;

// Definition of variable storing the total 'backorder quantity' in shopping cart
887:   var OosProductsTotal = 0;

// Definition of the variable storing 'available_later' text
921:     var available_later = product_list[i].available_later;

// JSON support for AVAILABILITY column
0991:     OosProducts = parseInt(product_list[i].quantity) - parseInt(product_list[i].quantity_available);
0992:     if (OosProducts > 0) {  
0993:       $('#outofstock_availability_' + key_for_blockcart).html(available_later +  ' (' + quantity + ': ' + OosProducts + ')');
0994:       $('#outofstock_availability_' + key_for_blockcart).show();
0995:     }
0996:     else {
0997:       $('#outofstock_availability_' + key_for_blockcart).hide();
0998:     }
0999:     nbrProducts += parseInt(product_list[i].quantity);
1000:     OosProductsTotal += OosProducts;
1001:   }

// JSON support for "delayed shipping" block
1004:   if (json.product_out_of_stock == 0 && json.product_in_stock > 0) {
1005:       if ((OosProducts-OosProductsTotal == 0 && OosProducts > 0) || (OosProducts-OosProductsTotal < 0 && OosProducts >= 0) || (OosProducts-OosProductsTotal < 0 && OosProducts < 0) || (OosProducts-OosProductsTotal > 0 && OosProducts > 0)) {
1006:             $('.allow_seperated_package').show();
1007:             $('.allow_seperated_package').css({'color':'white', 'background-color':'orange', 'padding':'10px', 'display':'inline-block'});
1008:       } else {
1009:             $('.allow_seperated_package').hide();
1010:           }
1011:   } else if(json.product_out_of_stock > 0 && json.product_in_stock == 0) {
1012:       $('.allow_seperated_package').hide();
1013:   } else {
1014:       $('.allow_seperated_package').show();
1015:   }


File: \themes\your_theme\shopping-cart.tpl -> I have modified the native "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 adventure with PrestaShop. If anyone has any suggestions I would bevery grateful.

Best regards,
Radoslaw

Edited by karcharoth (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...