Prestashop: 1.7.5 Carrier errors

Created on 14 Feb 2019  路  12Comments  路  Source: PrestaShop/PrestaShop

Describe the bug
Carrier in BO and FO has some trouble after migrate to 1.7.5. Sometimes I can't update Carrier (max_input_var=50000) adn I have 'Error thrown: [object Object] Text status: parsererror' .
For same configuration I have diff茅rents Carriers on FO, depending on my adresse (same Country) !
For my main localisation I can't show a Carrier configured without 'fees' or weight limit. -> it work on my local stage with the exact same configuration !
So this featured is not stable !

Screenshots
capture du 2019-02-14 18-36-59

Additionnal information
PrestaShop version: 1.7.5
PHP version: 7

1.7.5.0 BO Bug Carriers Fixed Minor

Most helpful comment

@khouloudbelguith This problem occur when AdminCarrierWizardController::processRanges()throw a PrestaShopException and response of ajax request is html instead of json so javascript fail and show the popup.

To reproduce the problem, with a fresh install :

  1. Edit the carrier named "My Carrier"
  2. Toggle the Billing method to According to total price. or According to total weight.
  3. Save
  4. Edit another time the carrier named "My Carrier"
  5. Toggle the Billing method to According to total price. or According to total weight.
  6. Save

Repeat this multiple time and you can see an error

You should see the error popup
You should have value in ps_range_price and ps_range_weight corresponding to current range.
id_carrier, delimiter1, delimiter2 corresponding to values of http header of the ajax request who failing

Explanation

    public function processRanges($id_carrier)
    {
        if (!$this->access('edit') || !$this->access('add')) {
            $this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');

            return;
        }

        $carrier = new Carrier((int) $id_carrier);
        if (!Validate::isLoadedObject($carrier)) {
            return false;
        }

        $range_inf = Tools::getValue('range_inf');
        $range_sup = Tools::getValue('range_sup');
        $range_type = Tools::getValue('shipping_method');

        $fees = Tools::getValue('fees');

        $carrier->deleteDeliveryPrice($carrier->getRangeTable());
        if ($range_type != Carrier::SHIPPING_METHOD_FREE) {
            foreach ($range_inf as $key => $delimiter1) {
                if (!isset($range_sup[$key])) {
                    continue;
                }
                $add_range = true;
                if ($range_type == Carrier::SHIPPING_METHOD_WEIGHT) {
                    if (!RangeWeight::rangeExist(null, (float) $delimiter1, (float) $range_sup[$key], $carrier->id_reference)) {
                        $range = new RangeWeight();
                    } else {

Here the function RangeWeight::rangeExist() find an existing range so behavior seems to update it with actual $carrier->id value

                        $range = new RangeWeight((int) $key);

But here we try to retrieve this existing range with $key value which is not the id_range_weight value but the value of the current element in $range_inf array who is equal to 0

                        $range->id_carrier = (int) $carrier->id;
                        $range->save();

$range->save(); throw a PrestaShopException('Property RangeWeight->delimiter1 is empty.')
Because it try to create a new RangeWeight() due to id = 0 moreover $range->delimiter1 is not set as it required in definition

                        $add_range = false;
                    }
                }

                if ($range_type == Carrier::SHIPPING_METHOD_PRICE) {
                    if (!RangePrice::rangeExist(null, (float) $delimiter1, (float) $range_sup[$key], $carrier->id_reference)) {
                        $range = new RangePrice();
                    } else {

Here the function RangePrice::rangeExist() find an existing range so behavior seems to update it with actual $carrier->id value

                        $range = new RangePrice((int) $key);

But here we try to retrieve this existing range with $key value which is not the id_range_price value but the value of the current element in $range_inf array who is equal to 0

                        $range->id_carrier = (int) $carrier->id;
                        $range->save();

$range->save(); throw a PrestaShopException('Property RangePrice->delimiter1 is empty.')
Because it try to create a new RangePrice() due to id = 0 moreover $range->delimiter1 is not set as it required in definition

                        $add_range = false;
                    }
                }
                if ($add_range) {
                    $range->id_carrier = (int) $carrier->id;
                    $range->delimiter1 = (float) $delimiter1;
                    $range->delimiter2 = (float) $range_sup[$key];
                    $range->save();
                }

                if (!Validate::isLoadedObject($range)) {
                    return false;
                }
                $price_list = array();
                if (is_array($fees) && count($fees)) {
                    foreach ($fees as $id_zone => $fee) {
                        $price_list[] = array(
                            'id_range_price' => ($range_type == Carrier::SHIPPING_METHOD_PRICE ? (int) $range->id : null),
                            'id_range_weight' => ($range_type == Carrier::SHIPPING_METHOD_WEIGHT ? (int) $range->id : null),
                            'id_carrier' => (int) $carrier->id,
                            'id_zone' => (int) $id_zone,
                            'price' => isset($fee[$key]) ? (float) str_replace(',', '.', $fee[$key]) : 0,
                        );
                    }
                }

                if (count($price_list) && !$carrier->addDeliveryPrice($price_list, true)) {
                    return false;
                }
            }
        }

        return true;
    }

Related issues :

All 12 comments

Hi @fundup,

Sorry, I did not manage to reproduce the issue with PS1.7.5.0, fresh installation & with upgrade from the previous version 1.7.4.4.
Could you please try to follow this comment & check if the issue occurs again.
Thanks!

Thanks, I seems to be related to this issue. I will try to fix and I'll notice you.

@fundup, thanks!
Waiting for your feedback.

Unfortunately your solution doesn't work. I modified carrier_wizard.js, cleared cache.
When I have this error modifying a carrier and I come back all rules are empty. After multiple refresh I'm abel to retrieve rules without explanations ...
I'm totaly lost ...
capture du 2019-02-19 10-49-48
capture du 2019-02-19 10-50-23

Hi @fundup,

We need to retrieve the PHP error log and the debug mode report in order to find out what's wrong.
In our case, we did not manage to reproduce this issue.
Don't you know how to get this information? Please read the following article:
http://build.prestashop.com/howtos/misc/how-to-create-bug-report/

Thanks!

Unfortunately I don't see any error in my Apache log, and debug mode is not helpfull :( .
I have a local version and server version (exactly the same configuration, same database). In my local version I don't have any trouble.
I was able to reproduce a similar error (saving with 0 as range value and empty price), after checking ajax call in my debug console I have in return (status 200 !!)
La propri茅t茅 RangeWeight->delimiter1 est vide. ( RangeWeight->delimiter1 is empty )
So it doesn't help me in my case, but at least please show this error correctly and not this 'Technical error'!

So I'm still debuging ...

After many tries I'm able to save my Carrier (don't know exactly why, I did this .

Well the problem still appear and it is always with this error : 'property RangeWeight->delimiter1 is empty'.

Steps to reproduce :

  • create a carrier with 2 zone and 3 ranges
  • Edit this carrier : disable one zone and add 1 range

You should have this error saving this carrier

@fundup, no, I did not manage to reproduce the issue with PS1.7.5.0.
https://drive.google.com/file/d/1j3omt6KC3NykwfWZInLuzEuzoqSlDMrr/view
Thanks!

@khouloudbelguith This problem occur when AdminCarrierWizardController::processRanges()throw a PrestaShopException and response of ajax request is html instead of json so javascript fail and show the popup.

To reproduce the problem, with a fresh install :

  1. Edit the carrier named "My Carrier"
  2. Toggle the Billing method to According to total price. or According to total weight.
  3. Save
  4. Edit another time the carrier named "My Carrier"
  5. Toggle the Billing method to According to total price. or According to total weight.
  6. Save

Repeat this multiple time and you can see an error

You should see the error popup
You should have value in ps_range_price and ps_range_weight corresponding to current range.
id_carrier, delimiter1, delimiter2 corresponding to values of http header of the ajax request who failing

Explanation

    public function processRanges($id_carrier)
    {
        if (!$this->access('edit') || !$this->access('add')) {
            $this->errors[] = $this->trans('You do not have permission to use this wizard.', array(), 'Admin.Shipping.Notification');

            return;
        }

        $carrier = new Carrier((int) $id_carrier);
        if (!Validate::isLoadedObject($carrier)) {
            return false;
        }

        $range_inf = Tools::getValue('range_inf');
        $range_sup = Tools::getValue('range_sup');
        $range_type = Tools::getValue('shipping_method');

        $fees = Tools::getValue('fees');

        $carrier->deleteDeliveryPrice($carrier->getRangeTable());
        if ($range_type != Carrier::SHIPPING_METHOD_FREE) {
            foreach ($range_inf as $key => $delimiter1) {
                if (!isset($range_sup[$key])) {
                    continue;
                }
                $add_range = true;
                if ($range_type == Carrier::SHIPPING_METHOD_WEIGHT) {
                    if (!RangeWeight::rangeExist(null, (float) $delimiter1, (float) $range_sup[$key], $carrier->id_reference)) {
                        $range = new RangeWeight();
                    } else {

Here the function RangeWeight::rangeExist() find an existing range so behavior seems to update it with actual $carrier->id value

                        $range = new RangeWeight((int) $key);

But here we try to retrieve this existing range with $key value which is not the id_range_weight value but the value of the current element in $range_inf array who is equal to 0

                        $range->id_carrier = (int) $carrier->id;
                        $range->save();

$range->save(); throw a PrestaShopException('Property RangeWeight->delimiter1 is empty.')
Because it try to create a new RangeWeight() due to id = 0 moreover $range->delimiter1 is not set as it required in definition

                        $add_range = false;
                    }
                }

                if ($range_type == Carrier::SHIPPING_METHOD_PRICE) {
                    if (!RangePrice::rangeExist(null, (float) $delimiter1, (float) $range_sup[$key], $carrier->id_reference)) {
                        $range = new RangePrice();
                    } else {

Here the function RangePrice::rangeExist() find an existing range so behavior seems to update it with actual $carrier->id value

                        $range = new RangePrice((int) $key);

But here we try to retrieve this existing range with $key value which is not the id_range_price value but the value of the current element in $range_inf array who is equal to 0

                        $range->id_carrier = (int) $carrier->id;
                        $range->save();

$range->save(); throw a PrestaShopException('Property RangePrice->delimiter1 is empty.')
Because it try to create a new RangePrice() due to id = 0 moreover $range->delimiter1 is not set as it required in definition

                        $add_range = false;
                    }
                }
                if ($add_range) {
                    $range->id_carrier = (int) $carrier->id;
                    $range->delimiter1 = (float) $delimiter1;
                    $range->delimiter2 = (float) $range_sup[$key];
                    $range->save();
                }

                if (!Validate::isLoadedObject($range)) {
                    return false;
                }
                $price_list = array();
                if (is_array($fees) && count($fees)) {
                    foreach ($fees as $id_zone => $fee) {
                        $price_list[] = array(
                            'id_range_price' => ($range_type == Carrier::SHIPPING_METHOD_PRICE ? (int) $range->id : null),
                            'id_range_weight' => ($range_type == Carrier::SHIPPING_METHOD_WEIGHT ? (int) $range->id : null),
                            'id_carrier' => (int) $carrier->id,
                            'id_zone' => (int) $id_zone,
                            'price' => isset($fee[$key]) ? (float) str_replace(',', '.', $fee[$key]) : 0,
                        );
                    }
                }

                if (count($price_list) && !$carrier->addDeliveryPrice($price_list, true)) {
                    return false;
                }
            }
        }

        return true;
    }

Related issues :

If someone like me is in trouble facing client and explaining that you can't update a carrier... Here is a trick to manually upate it.
Step 1 : create a new Carrier with new parameters.
Step 2 : in DB _carrier find your old Carrier with his ID and note the id_reference, then put 0 on deleted column.
Step 3 : in DB _carrier find your new Carrier created and set id_reference with the old one.

Definitely not a solution but if you are in trouble it can help ....

Hi @Matt75,

Thanks a lot for your feedback & your fix.
Thank you!

@fundup this is now fixed in develop branch and will be shipped with PS 1.7.6 thanks to the work of @Matt75 in https://github.com/PrestaShop/PrestaShop/pull/12946

Was this page helpful?
0 / 5 - 0 ratings