movingit Posted September 12, 2017 Share Posted September 12, 2017 (edited) Prestashop 1.6.1.15: When we add a tracking code with the webservice API, we see it back in the backoffice as expected: We use the PSWebServiceLibrary: $xml = $webService->edit(array('resource' => 'order_carriers','id'=>xxx,'putXml' => $xml->asXML())); Conclusion: tracking code has been added succesfully. After this we change the order status to "in transit" and the in_transit email is send to the customer. Problem: The {followup} tag in the email is not replaced with the right and complete URL. When we change the tracking code in the backoffice, and save it again without changing anything, and resend the email, the email is complete with the link in stead of {followup} in the email. Looks like adding the tracking code via the webservice, was not completely succesfull? What can we do? We already have changed these files according old posts found on the forum/internet: Both trying to fill the {followup} parameter because it looks like this one is not filled? controllers/admin/AdminOrdersController.php classes/order/OrderHistory.php These changes had no effect. Edited September 12, 2017 by movingit (see edit history) Link to comment Share on other sites More sharing options...
GSL Posted October 3, 2017 Share Posted October 3, 2017 Nobody who can help with a solution to this problem? Link to comment Share on other sites More sharing options...
bellini13 Posted October 3, 2017 Share Posted October 3, 2017 I can't speak about the webservice, but the admin order controller updates the tracking number in 2 places in the database 1) $order->shipping_number = Tools::getValue('tracking_number'); 2) $order_carrier->tracking_number = pSQL(Tools::getValue('tracking_number')); That translates to the shipping_number column on the ps_orders table, and tracking_number on the ps_order_carrier table When you change the order status to Shipped, Prestashop only uses the shipping_number from the orders table So you should confirm that both of these columns are updated when using the webservice, but ensure that the shipping_number from the orders table is Link to comment Share on other sites More sharing options...
movingit Posted October 3, 2017 Author Share Posted October 3, 2017 Thanks for the tip. We update the shipping number and tracking number both individually now before updating the order status. I will send a reply if we now is this did the trick. Link to comment Share on other sites More sharing options...
movingit Posted October 5, 2017 Author Share Posted October 5, 2017 Unfortuniatly, this did not fix the problem. Both numbers (tracking number in order_carrier and shipping number in orders) are filled in the database with an API call. After that we change the order status succesfully, also with an API call. This triggers the "in transit" mail to the customer, but the tracking URL still shows as {followup} If we edit the tracking code in the back office and save, without changing the code, and send the email again, the URL shows fine. Link to comment Share on other sites More sharing options...
movingit Posted October 24, 2017 Author Share Posted October 24, 2017 If we request order information with the API, the shipping number is filled, but in the database (orders table) the shipping number is still empy, where is the shipping code we see wehen requesting for the order details? Link to comment Share on other sites More sharing options...
hakeryk2 Posted October 25, 2017 Share Posted October 25, 2017 (edited) In which table You are exacly looking for this tracking number? In ps_orders column shipping_number is deprecated and proper one is stored in ps_order_carrier in tracking_number I know what might be an issue which with I was struggling to. Propably API is using function setCurrentState which doesn't trigger setting email template vars and my workaround for this was creating an override for setCurrentState in override/classes/Order.php with this code if You already have some changes in this class: public function setCurrentState($id_order_state, $id_employee = 0) { if (empty($id_order_state)) { return false; } $history = new OrderHistory(); $history->id_order = (int)$this->id; $history->id_employee = (int)$id_employee; $history->changeIdOrderState((int)$id_order_state, $this); $res = Db::getInstance()->getRow(' SELECT `invoice_number`, `invoice_date`, `delivery_number`, `delivery_date` FROM `'._DB_PREFIX_.'orders` WHERE `id_order` = '.(int)$this->id); $this->invoice_date = $res['invoice_date']; $this->invoice_number = $res['invoice_number']; $this->delivery_date = $res['delivery_date']; $this->delivery_number = $res['delivery_number']; $this->update(); if ($id_order_state == Configuration::get('PS_OS_SHIPPING')) { $order = new Order($history->id_order); if ($order->shipping_number) { $templateVars = array( '{followup}' => $order->shipping_number, '{shipping_number}' => $order->shipping_number, '{order_name}' => $order->reference ); } $history->addWithemail(true, $templateVars); } else { $history->addWithemail(); } } or download the attached file Order.php to this post, insert in override/classes/ and after that go to /cache folder and remove file class_index.php For me it helped in 1.6.1.4 Order.php Edited October 25, 2017 by hakeryk2 (see edit history) Link to comment Share on other sites More sharing options...
movingit Posted November 2, 2017 Author Share Posted November 2, 2017 (edited) Hello, Unfortiniatly the override does not solve the problem. When I add the tracking number in the backoffice everything works fine. I believe this is triggered by this code (controllers/admin/AdminOrdersController.php): // Update order_carrier $order_carrier->tracking_number = pSQL(Tools::getValue('tracking_number')); if ($order_carrier->update()) { // Send mail to customer $customer = new Customer((int)$order->id_customer); $carrier = new Carrier((int)$order->id_carrier, $order->id_lang); if (!Validate::isLoadedObject($customer)) throw new PrestaShopException('Can\'t load Customer object'); if (!Validate::isLoadedObject($carrier)) throw new PrestaShopException('Can\'t load Carrier object'); $templateVars = array( '{followup}' => str_replace('@', $order->shipping_number, $carrier->url), '{firstname}' => $customer->firstname, '{lastname}' => $customer->lastname, '{id_order}' => $order->id, '{shipping_number}' => $order->shipping_number, '{order_name}' => $order->getUniqReference() ); if (@Mail::Send((int)$order->id_lang, 'in_transit', Mail::l('Package in transit', (int)$order->id_lang), $templateVars, $customer->email, $customer->firstname.' '.$customer->lastname, null, null, null, null, _PS_MAIL_DIR_, true, (int)$order->id_shop)) { Hook::exec('actionAdminOrdersTrackingNumberUpdate', array('order' => $order, 'customer' => $customer, 'carrier' => $carrier), null, false, true, false, $order->id_shop); Tools::redirectAdmin(self::$currentIndex.'&id_order='.$order->id.'&vieworder&conf=4&token='.$this->token); } else $this->errors[] = Tools::displayError('An error occurred while sending an email to the customer.'); } After doing this, the shipping_number in the orders table is filled. I try to do the same with the following API calls (using the default PSWebserviceLibrary from GIT): First add tracking code: $xml = $webService->get(array('resource' => 'order_carriers','id'=>$carrier->order_carriers[0]->order_carrier->id)); $xml->order_carrier->tracking_number = $p_sUrl; $xml = $webService->edit(array('resource' => 'order_carriers','id'=>$carrier->order_carriers[0]->order_carrier->id,'putXml' => $xml->asXML())); After that, update status: $xml = $webService->get(array('resource' => 'order_histories?schema=blank')); $xml->order_history->id_order = $p_iOrderID; $xml->order_history->id_order_state = $p_iStatusID; $xml->order_history->id_employee = $this->m_iPSUser; unset($xml->order_history->id); unset($xml->order_history->date_add); $xml = $webService->add(array('resource' => 'order_histories?sendemail='.$bSendEmail,'postXml' => $xml->asXML())); The results are: 1: Tracking code is visible in backoffice 2: status is set to right id (send) 3: In the database, shipping_number in the orders table is still empty 4: in_transit mail is send with the text: {followup} It looks like the API call does not execute the same code in the adminOrdersController class, but does something else? I also tried to adjust your override file with: class Order extends OrderCore { public function setCurrentState($id_order_state, $id_employee = 0) { if (empty($id_order_state)) { return false; } $history = new OrderHistory(); $history->id_order = (int)$this->id; $history->id_employee = (int)$id_employee; $history->changeIdOrderState((int)$id_order_state, $this); $res = Db::getInstance()->getRow(' SELECT O.invoice_number, O.invoice_date, O.delivery_number, O.delivery_date, O.id_order_carrier,C.tracking_number,V.url FROM '._DB_PREFIX_.'orders AS O LEFT JOIN '._DB_PREFIX_.'order_carrier AS C ON O.id_order= C.id_order WHERE O.id_order = '.(int)$this->id); $this->invoice_date = $res['invoice_date']; $this->invoice_number = $res['invoice_number']; $this->delivery_date = $res['delivery_date']; $this->delivery_number = $res['delivery_number']; $this->shipping_number = $res['tracking_number']; $this->update(); if ($id_order_state == Configuration::get('PS_OS_SHIPPING')) { $order = new Order($history->id_order); $order_carrier = new OrderCarrier(Tools::getValue('id_order_carrier')); if ($order->shipping_number) { $templateVars = array( '{followup}' => str_replace('@', $res['tracking_number'], $res['url']), '{shipping_number}' => $order->shipping_number, '{order_name}' => $order->reference ); } $history->addWithemail(true, $templateVars); } else { $history->addWithemail(); } } } But this doesn't have any effect. If I request for order information: $opt = array('resource'=>'orders', 'id'=>$p_iOrderID); $xml = $webService->get($opt); var_dump($xml); We see that the parameter $xml->order->shipping_number is filled with the correct tracking number. The shipping number is still empty in the orders table tough. Also when we change the value in the database to for example "123" we still get the right tracking code from de order carries table in this parameter. To me it looks like it does not have anything to do with the shipping number, but filling the email template with right parameters. But where can I influence this? Hope you can help me further, thanks Edited November 2, 2017 by movingit (see edit history) Link to comment Share on other sites More sharing options...
gabrielnbrazil Posted February 7, 2018 Share Posted February 7, 2018 (edited) Hi, I think I found a solution for this problem. Searching on the internet found on a integrator app called CartRover that make a fix for this. https://cartrover.atlassian.net/wiki/spaces/CART/pages/34177028/Blank+Tracking+Number+-+PrestaShop Will paste the solution here in case the information goes down. PrestaShop server admin needs to modify two source files: Order.php & WebserviceRequest.php Modify classes/order/Order.php: Please open PrestaShop root directory on server. Make sure that you have permission to modify PrestaShop source files. Go to classes/order directory, and open Order.php. Find function setWsShippingNumber($shipping_number) (around line 2215), and insert the following line as marked: public function setWsShippingNumber($shipping_number) { $id_order_carrier = Db::getInstance()->getValue(' SELECT `id_order_carrier` FROM `'._DB_PREFIX_.'order_carrier` WHERE `id_order` = '.(int)$this->id); if ($id_order_carrier) { $order_carrier = new OrderCarrier($id_order_carrier); $order_carrier->tracking_number = $shipping_number; $this->shipping_number = $shipping_number; // <----------Insert this line ! $order_carrier->update(); } else { $this->shipping_number = $shipping_number; } return true; } Find function setCurrentState($id_order_state, $id_employee = 0) (around line 1545), and add following lines to that function: public function setCurrentState($id_order_state, $id_employee = 0) { if (empty($id_order_state)) { return false; } $history = new OrderHistory(); $history->id_order = (int)$this->id; $history->id_employee = (int)$id_employee; $history->changeIdOrderState((int)$id_order_state, $this); $res = Db::getInstance()->getRow(' SELECT `invoice_number`, `invoice_date`, `delivery_number`, `delivery_date` FROM `'._DB_PREFIX_.'orders` WHERE `id_order` = '.(int)$this->id); $this->invoice_date = $res['invoice_date']; $this->invoice_number = $res['invoice_number']; $this->delivery_date = $res['delivery_date']; $this->delivery_number = $res['delivery_number']; $this->update(); $carrier = new Carrier($this->id_carrier, $this->id_lang); // <----------Insert this line ! $template_vars = array( // <----------Insert this line ! '{shipping_number}' => $this->shipping_number, // <----------Insert this line ! '{followup}' => str_replace('@', $this->shipping_number, $carrier->url), // <----------Insert this line ! ); // <----------Insert this line ! $history->addWithemail(true, $template_vars); } '{shipping_number}' should match Tracking Number placeholder in your Email Template. '{followup}' should match Tracking URL placeholder in your Email Template. Make sure to save Order.php file before you close it. Modify classes/webservice/WebserviceRequest.php: Go to classes/webservice directory, and open file WebserviceRequest.php. Find function saveEntityFromXml($successReturnCode) (around line 1371), and insert following lines (around line 1425): foreach ($xmlEntities as $xmlEntity) { /** @var SimpleXMLElement $xmlEntity */ $attributes = $xmlEntity->children(); /** @var ObjectModel $object */ $retrieve_data = $this->resourceConfiguration['retrieveData']; if ($this->method == 'POST') { $object = new $retrieve_data['className'](); } elseif ($this->method == 'PUT') { $object = new $retrieve_data['className']((int)$attributes->id); if (!$object->id) { $this->setError(404, 'Invalid ID', 92); return false; } } $this->objects[] = $object; $i18n = false; if(!empty($this->resourceConfiguration['fields']['current_state'])){ // <----------Insert this line! (Around Line 1425) $prop = $this->resourceConfiguration['fields']['current_state']; // <----------Insert this line! unset($this->resourceConfiguration['fields']['current_state']); // <----------Insert this line! $this->resourceConfiguration['fields']['current_state'] = $prop; // <----------Insert this line! } // <----------Insert this line! // attributes foreach ($this->resourceConfiguration['fields'] as $fieldName => $fieldProperties) { $sqlId = $fieldProperties['sqlId']; if ($fieldName == 'id') { $sqlId = $fieldName; } if (isset($attributes->$fieldName) && isset($fieldProperties['sqlId']) && (!isset($fieldProperties['i18n']) || !$fieldProperties['i18n'])) { if (isset($fieldProperties['setter'])) { Make sure to save WebserviceRequest.php before you close it. Upload to server and clean cache. Edited August 4, 2018 by razaro Code without proper format (see edit history) 1 Link to comment Share on other sites More sharing options...
micelio Posted February 24, 2019 Share Posted February 24, 2019 ho provato la soluzione di gabrielnbrazil me sembra che non funziona con il mio problema.. ho creato un post qui: funziona tutto a parte il link che sembra rotto.. Link to comment Share on other sites More sharing options...
ukbaz Posted October 19, 2020 Share Posted October 19, 2020 Hi I'm having an issue with Tracking URL using ShipStation. It insets correct tracking number via Webservice, but does not overwrite the carrier URL set in Prestashop if carrier used is different from the one selected at checkout. So for example - customer chooses Royal Mail delivery in Prestashop, but in Shipstation I elect to send it FBA. The resulting tracking URL is linkt to Royal Mail tracking with correct tracking number, but doesn't work as it's the incorrect URL. Can the above solution help with overriding tracking URL in webservice? Thanks Baz Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now