Overview

Packages

  • Eabi
    • Dpd
  • None
  • PHP

Classes

  • dpdcodpayment
  • eabi_dpd_courier
  • Eabi_dpd_courierCourierModuleFrontController
  • eabi_dpd_parcelstore
  • eabi_dpd_parcelstore_data_send_executor
  • eabi_dpd_parcelstore_dpd_api
  • eabi_dpd_parcelstore_dpd_helper
  • eabi_dpd_parcelstore_html_helper
  • eabi_dpd_parcelstore_validator_helper
  • Eabi_dpd_parcelstoreCourierModuleFrontController
  • Eabi_Postoffice
  • eabi_postoffice_dialcode_helper
  • Eabi_PostofficePostofficeModuleFrontController

Functions

  • upgrade_module_0_3
  • upgrade_module_0_6
  • upgrade_module_0_8
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /*
  4:   
  5:  *
  6:  * NOTICE OF LICENSE
  7:  *
  8:  * This source file is subject to the Open Software License (OSL 3.0)
  9:  * or OpenGPL v3 license (GNU Public License V3.0)
 10:  * that is bundled with this package in the file LICENSE.txt.
 11:  * It is also available through the world-wide-web at this URL:
 12:  * http://opensource.org/licenses/osl-3.0.php
 13:  * or
 14:  * http://www.gnu.org/licenses/gpl-3.0.txt
 15:  * If you did not receive a copy of the license and are unable to
 16:  * obtain it through the world-wide-web, please send an email
 17:  * to info@e-abi.ee so we can send you a copy immediately.
 18:  *
 19:  * DISCLAIMER
 20:  *
 21:  * Do not edit or add to this file if you wish to upgrade this module to newer
 22:  * versions in the future.
 23:  *
 24:  * @category   Eabi
 25:  * @package    Eabi_Dpd
 26:  * @copyright  Copyright (c) 2014 Aktsiamaailm LLC (http://en.e-abi.ee/)
 27:  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 28:  * @license    http://www.gnu.org/licenses/gpl-3.0.txt  GNU Public License V3.0
 29:  * @author     Matis Halmann
 30:  * 
 31: 
 32:  */
 33: if (!defined('_PS_VERSION_')) {
 34:     exit;
 35: }
 36: 
 37: /**
 38:  * <p>Handles Order DPD courier to pickup goods commands when DPD parcelstore is enabled.</p>
 39:  * <p>This controller is included in the front, because PrestaShop does not support backend URLs for the modules without creating menu item for it first.</p>
 40:  * <p>It is only checked that user would be at least logged in the admin.</p>
 41:  *
 42:  * @author Matis
 43:  */
 44: class Eabi_dpd_parcelstoreCourierModuleFrontController extends ModuleFrontController {
 45:     
 46:     /**
 47:      * <p>Used only on PHP5.2 environment where datetime does not support setTimeStamp function correctly</p>
 48:      * @var int
 49:      */
 50:     protected $_timestampDiff = null;
 51:     
 52:     
 53:     protected $_dateFormat = 'yyyy-MM-dd';
 54:     protected $_timeFormat = 'Hi';
 55:     protected $_timeFormatNice = 'H:i';
 56:     
 57:     protected $_availableDates;
 58:     protected $_apiResult;
 59:     
 60:     
 61:     /**
 62:      * <p>Exits script with message not logged in message when user is not logged in as admin.</p>
 63:      */
 64:     public function __construct() {
 65:         $cookie = new Cookie('psAdmin');
 66:         
 67:         $isAdmin = false;
 68: 
 69:         if ($cookie->id_employee) {
 70:             $isAdmin = true;
 71:         }
 72:         if (!$isAdmin) {
 73:             echo 'not logged in';
 74:             exit;
 75:         }
 76: 
 77:         parent::__construct();
 78:     }
 79:     
 80:     
 81:     /**
 82:      * <p>Sends courier call pickup goods action to DPD server and returns information about its status.</p>
 83:      * <p>Available POST params:</p>
 84:      * <ul>
 85:          <li><b>Po_remark</b> - Note to sent to courier</li>
 86:          <li><b>Po_Date</b> - Date when courier should pick up goods. Format: YYYY-MM-DD</li>
 87:          <li><b>Po_Time</b> - Time range when courier should pick up goods. Format: HMM-HMM (timefrom-timetill)</li>
 88:          <li><b>Po_envelope_qty</b> - Number of envelopes courier should pick up</li>
 89:          <li><b>Po_parcel_qty</b> - Number of parcels courier should pick up</li>
 90:          <li><b>Po_pallet_qty</b> - Number of pallets courier should pick up</li>
 91:      </ul>
 92:      * @return boolean|array
 93:      */
 94:     public function initContent() {
 95:             if ($this->_timestampDiff === null) {
 96:                 $this->_timestampDiff = $this->_getTimestampOffset(2);
 97:             }
 98:         $params = $_POST;
 99:         try {
100:             $prefix = eabi_dpd_parcelstore::ORDER_COMMENT_START_PREFIX;
101: 
102:             $api = $this->_getDpdHelper()->getApi(Context::getContext()->shop->id, eabi_dpd_parcelstore::CONST_PREFIX);
103:             $isCourierComing = $api->isCourierComing();
104:             if (isset($params['Po_Date']) && $params['Po_Date'] != '-' && !$isCourierComing) {
105:                 $orderSendData = array(
106:                     'Po_remark' => isset($params['Po_remark']) ? $params['Po_remark'] : '',
107:                     'Po_type' => 'PO',
108:                     'Po_Date' => $params['Po_Date'],
109:                     'Po_Time_from' => $this->_getTimeFrom($params['Po_Time']),
110:                     'Po_Time_til' => $this->_getTimeTil($params['Po_Time']),
111:                     'Po_envelope_qty' => $params['Po_envelope_qty'],
112:                     'Po_parcel_qty' => $params['Po_parcel_qty'],
113:                     'Po_pallet_qty' => $params['Po_pallet_qty'],
114:                     'Sh_envelope_qty' => $params['Po_envelope_qty'],
115:                     'Sh_parcel_qty' => $params['Po_parcel_qty'],
116:                     'Sh_pallet_qty' => $params['Po_pallet_qty'],
117:                     'Sh_pudo' => 'false',
118:                 );
119:                 $orderSendResult = $api->autoSendData($orderSendData);
120:                 $courierArrivalDate = $orderSendData['Po_Date'];
121:                 $courierArrivalTime = $orderSendData['Po_Time_from'] . ' ' . $this->module->l('and') . ' ' . $orderSendData['Po_Time_til'];
122: 
123:                 $pickupTimeFrom = new DateTime();
124:                 $this->setTimestamp($pickupTimeFrom, 0);
125: //                $pickupTimeFrom->setTimestamp(0);
126:                 $pickupTimeFrom->setTimezone(new DateTimeZone('ETC/GMT+0'));
127: 
128:                 $dateParts = explode('-', $orderSendData['Po_Date']);
129:                 $pickupTimeFrom->setDate($dateParts[0], $dateParts[1], $dateParts[2]);
130: 
131:                 //TODO: set days
132:                 //we need this shitty way, because setting time directly with one format definition results in wrong timestamp                
133:                 if (strlen($orderSendData['Po_Time_from']) > 2) {
134: //                $pickupTimeFrom->add(substr($orderSendData['Po_Time_from'], strlen($orderSendData['Po_Time_from']) - 2), Zend_Date::MINUTE);
135:                     $this->setTimestamp($pickupTimeFrom, $pickupTimeFrom->format('U') + (substr($orderSendData['Po_Time_from'], strlen($orderSendData['Po_Time_from'])) * 60));
136:                     $this->setTimestamp($pickupTimeFrom, $pickupTimeFrom->format('U') + (substr($orderSendData['Po_Time_from'], -4, 2) * 60 * 60));
137: //                    $pickupTimeFrom->setTimestamp($pickupTimeFrom->format('U') + (substr($orderSendData['Po_Time_from'], strlen($orderSendData['Po_Time_from'])) * 60));
138: //                    $pickupTimeFrom->setTimestamp($pickupTimeFrom->format('U') + (substr($orderSendData['Po_Time_from'], -4, 2) * 60 * 60));
139:                 } else {
140: //                    $pickupTimeFrom->add($orderSendData['Po_Time_from'], 'H');
141: //                    $pickupTimeFrom->setTimestamp($pickupTimeFrom->format('U') + ($orderSendData['Po_Time_from'] * 60 * 60));
142:                     $this->setTimestamp($pickupTimeFrom, $pickupTimeFrom->format('U') + ($orderSendData['Po_Time_from'] * 60 * 60));
143:                 }
144: 
145: 
146:                 $pickupTimeTill = new DateTime();
147: //                $pickupTimeTill->setTimestamp(0);
148:                 $this->setTimestamp($pickupTimeTill, 0);
149:                 $pickupTimeTill->setTimezone(new DateTimeZone('ETC/GMT+0'));
150:                 $pickupTimeTill->setDate($dateParts[0], $dateParts[1], $dateParts[2]);
151: 
152:                 //TODO: set days
153:                 //we need this shitty way, because setting time directly with one format definition results in wrong timestamp                
154:                 if (strlen($orderSendData['Po_Time_til']) > 2) {
155: //                    $pickupTimeTill->setTimestamp($pickupTimeTill->format('U') + (substr($orderSendData['Po_Time_til'], strlen($orderSendData['Po_Time_til'])) * 60));
156: //                    $pickupTimeTill->setTimestamp($pickupTimeTill->format('U') + (substr($orderSendData['Po_Time_til'], -4, 2) * 60 * 60));
157:                     $this->setTimestamp($pickupTimeTill, $pickupTimeTill->format('U') + (substr($orderSendData['Po_Time_til'], strlen($orderSendData['Po_Time_til'])) * 60));
158:                     $this->setTimestamp($pickupTimeTill, $pickupTimeTill->format('U') + (substr($orderSendData['Po_Time_til'], -4, 2) * 60 * 60));
159:                 } else {
160: //                    $pickupTimeTill->setTimestamp($pickupTimeTill->format('U') + ($orderSendData['Po_Time_til'] * 60 * 60));
161:                     $this->setTimestamp($pickupTimeTill, $pickupTimeTill->format('U') + ($orderSendData['Po_Time_til'] * 60 * 60));
162:                 }
163: 
164: 
165:                 $configTimeStamp = $pickupTimeFrom->format('U') . ',' . $pickupTimeTill->format('U');
166:                 Configuration::updateValue(eabi_dpd_parcelstore::CONST_PREFIX . 'COURIER_PICKUP_TIME', $configTimeStamp);
167:             } else {
168:                 $this->context->smarty->assign(array(
169:                     'availableDates' => $this->getAvailableDates(),
170:                     'availableTimes' => $this->getAvailabeTimes(),
171:                     'requests' => '',//'<pre>'.htmlspecialchars(print_r($api->getLoggedRequests(), true)).'</pre>',
172:                 ));
173:                 
174:                 if (!$isCourierComing) {
175:                     $result = array(
176:                         'needs_reload' => true,
177:                         'is_action_error' => false,
178:                         'html' => $this->context->smarty->fetch($this->getTemplatePath().'courier.tpl'),
179:                     );
180:                     die(json_encode($result));
181:                     return $result;
182:                     
183:                 } else {
184:                     $pickupTimeFrom = new DateTime();
185:                     $pickupTimeTill = new DateTime();
186:                     $pickupTimeFrom->setTimezone(new DateTimeZone('ETC/GMT+0'));
187:                     $pickupTimeTill->setTimezone(new DateTimeZone('ETC/GMT+0'));
188:                     $this->setTimestamp($pickupTimeFrom, $isCourierComing[0]);
189:                     $this->setTimestamp($pickupTimeTill, $isCourierComing[1]);
190: //                    $pickupTimeFrom->setTimestamp($isCourierComing[0]);
191: //                    $pickupTimeTill->setTimestamp($isCourierComing[1]);
192:                     $courierArrivalDate = $pickupTimeFrom->format(Context::getContext()->language->date_format_lite);
193:                     $courierArrivalTime = $pickupTimeFrom->format('G') . ' ' . $this->module->l('and') . ' ' . $pickupTimeTill->format('G');
194:                     
195:                     
196:                 }
197:             }
198:             
199:             
200:             
201:             
202:             
203:         } catch (Exception $e) {
204:             $result = array(
205:                 'errors' => array($e->getMessage()),
206:                 'needs_reload' => true,
207:                 'is_action_error' => false,
208:             );
209:             die(json_encode($result));
210:             return $result;
211:         }
212:         $result = array(
213:             'messages' => array(sprintf($this->module->l('Courier comes to pick up your shipment on %1$s between %2$s'), $courierArrivalDate, $courierArrivalTime)),
214:             'needs_reload' => true,
215:             'is_action_error' => false,
216:         );
217:         die(json_encode($result));
218:         return $result;
219:     }
220:     
221:     /**
222:      * <p>Emulates DateTime::setTimeStamp for PHP 5.2</p>
223:      * @param DateTime $dateTime
224:      * @param int $timeStamp
225:      */
226:     protected function setTimestamp(DateTime &$dateTime, $timeStamp, $ignoreOffset = true) {
227:         if (method_exists($dateTime, 'setTimestamp')) {
228:             $dateTime->setTimestamp($timeStamp);
229:             return;
230:         }
231:         $offset = 0;
232:         if ($timeStamp != 0) {
233:             if ((int)$this->_timestampDiff) {
234:                 $offset = (int)$this->_timestampDiff;
235:             }
236:         }
237:         if (!$ignoreOffset && $timeStamp != 0) {
238:             $offset = $dateTime->getOffset();
239:         }
240:         $timeStamp += $offset;
241: 
242:         //we need to emulate
243:         $dateTime->setDate(date('Y', $timeStamp), date('n', $timeStamp), date('d', $timeStamp));
244:         $dateTime->setTime(date('G', $timeStamp), date('i', $timeStamp), date('s', $timeStamp));
245:     }
246: 
247:     /**
248:      * 
249:      * @return eabi_dpd_parcelstore_dpd_helper
250:      */
251:     protected function _getDpdHelper() {
252:         return $this->module->_getHelperModule()->helper('dpd_helper', eabi_dpd_parcelstore::NAME);
253:     }
254:     
255:     /**
256:      * 
257:      * @param string $input
258:      * @return string
259:      */
260:     protected function _getTimeFrom($input) {
261:         $parts = explode('-', $input);
262:         return str_replace('00', '', $parts[0]);
263:     }
264:     protected function _getTimeTil($input) {
265:         $parts = explode('-', $input);
266:         return str_replace('00', '', $parts[1]);
267:     }
268:     
269:     
270:     /**
271:      * <p>Fetches list of available pickup dates from DPD server and returns it as HTML select string</p>
272:      * @return string
273:      */
274:     private function getAvailableDates() {
275:         if ($this->_availableDates) {
276:             return $this->_availableDates;
277:         }
278:         $showOnlyDates = false;
279:         $datesResult = $this->_getDpdHelper()
280:                 ->getApi(Context::getContext()->shop->id, eabi_dpd_parcelstore::CONST_PREFIX)->getCourierCollectionTimes();
281:         $this->_apiResult = $datesResult;
282:         $dateObj = null;
283: 
284:         $resultString = '';
285: //        $resultString .= '<pre>'.htmlspecialchars(print_r($datesResult, true)).'</pre>';
286:             $resultString .= '<select name="Po_Date" id="Po_date" onchange="updateDpdEeTimes(this);">';
287:             $resultString .= '<option value="-">'.$this->module->l(' - select pickup date - ').'</option>';
288: 
289:         foreach ($datesResult['Po_date'] as $dateString) {
290:             $dateParts = explode('-', $dateString);
291:             if ((date('Ymd') == date('Ymd', mktime(0, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0]))) && !$showOnlyDates) {
292:                 //today
293:                 $resultString .= $this->_getDateInputLabel($this->module->l('Today'), $dateString);
294:             } else if ((date('Ymd') == date('Ymd', mktime(0, 0, 0, $dateParts[1], $dateParts[2] - 1, $dateParts[0]))) && !$showOnlyDates) {
295:                 //tomorrow
296:                 $resultString .= $this->_getDateInputLabel($this->module->l('Tomorrow'), $dateString);
297:             } else {
298:                 //other dates
299:                 $resultString .= $this->_getDateInputLabel($dateString, $dateString);
300:             }
301:         }
302:         $resultString .= '</select>';
303: 
304:         //do availabletimes as well
305:         $this->_availableDates = $resultString;
306:         return $this->_availableDates;
307:     }
308:     
309:     
310:     /**
311:      * <p>Fetches available pickup times from DPD server and returns it as json encoded object</p>
312:      * <p>Format:</p>
313:      * <pre>
314:      *  array(
315:      *      '2013-12-24' => 'html select menu with available time ranges',
316:      *      '2013-12-25' => 'html select menu with available time ranges',
317:      *      ....
318:      * );
319:      * </pre>
320:      * @return string
321:      */
322:     public function getAvailabeTimes() {
323:         if (!$this->_apiResult) {
324:             $this->getAvailableDates();
325:         }
326:         $availableTimes = array();
327:         $timeDateObject = null;
328:         //array key is date, content is html with select menu
329:         $availableTimes["-"] = $this->module->l('Select pickup date first');
330:         foreach ($this->_apiResult['Po_date'] as $key => $dateString) {
331:             if ($this->_timestampDiff === null) {
332:                 $this->_timestampDiff = $this->_getTimestampOffset(2);
333:             }
334:             
335:             
336:             $timeFrom = $this->_normalizeTime($this->_apiResult['Po_time_from'][$key]);
337:             $timeTo = $this->_normalizeTime($this->_apiResult['Po_time_til'][$key]);
338:             
339:             $timeWindow = $this->_normalizeTime($this->_apiResult['Minimal_time_window'][$key]);
340:             $availableTimes[$dateString] = $this->_getTimeSelectMenu($timeFrom, $timeTo, $timeWindow);
341:         }
342:         return json_encode($availableTimes);
343:     }
344:     
345:     
346:     /**
347:      * <p>Calculates offset for helping to simulate DateTime::setTimestamp function for PHP5.2</p>
348:      * @param int $hours
349:      * @return int
350:      */
351:     protected function _getTimestampOffset($hours) {
352:         $dateTime = $this->_normalizeTime($hours);
353:         $expectedResult = (int)($hours * 3600);
354:         $this->setTimestamp($dateTime, $expectedResult);
355:         $actualResult = $dateTime->format('U');
356:         $diff = $expectedResult - $actualResult;
357:         return $diff;
358:     }
359:     
360:     
361:     protected function _getDateInputLabel($label, $value) {
362:         return '<option value="'.  htmlspecialchars($value).'" >'.  htmlspecialchars($label).'</option>';
363:     }
364:     
365:     
366:     /**
367:      * <p>Takes earliest possible time, latest possible time, minimum allowed timewindow and renders it into one select menu with pickup time ranges.</p>
368:      * <p>All arguments have to be within same date.</p>
369:      * <p>Pickup time ranges are always displayed within narrowest possible timewindow.</p>
370:      * @param DateTime $timeFrom earliest time possible
371:      * @param DateTime $timeTo latest time possible
372:      * @param DateTime $timeWindow minimal allowed time between start and end time.
373:      * @return string HTML select menu
374:      */
375:     protected function _getTimeSelectMenu($timeFrom, $timeTo, $timeWindow) {
376:         $position = $timeFrom->format('H');
377:         $result = '<select name="Po_Time" id="Po_Time">';
378:         do {
379:             $endTime = clone $timeFrom;
380: //            $endTime->setTimestamp($endTime->format('U') + $timeWindow->format('U'));
381:             $this->setTimestamp($endTime, $endTime->format('U') + $timeWindow->format('U'));
382:             if ($endTime->format('U') < $timeTo->format('U')) {
383:                 $timeDisplay = htmlspecialchars(ltrim($timeFrom->format($this->_timeFormat), '0') . '-' . ltrim($endTime->format($this->_timeFormat), '0'));
384:                 $timeDisplayNice = htmlspecialchars($timeFrom->format($this->_timeFormatNice) . '-' . $endTime->format($this->_timeFormatNice));
385:             } else {
386:                 $timeDisplay = htmlspecialchars(ltrim($timeFrom->format($this->_timeFormat), '0') . '-' . ltrim($endTime->format($this->_timeFormat), '0'));
387:                 $timeDisplayNice = htmlspecialchars($timeFrom->format($this->_timeFormatNice) . '-' . $endTime->format($this->_timeFormatNice));
388:             }
389:             $result .= '<option value="' . $timeDisplay . '">' . $timeDisplayNice . '</option>';
390: //            $timeFrom->setTimestamp($timeFrom->format('U') + 60 * 60);
391:             $this->setTimestamp($timeFrom, $timeFrom->format('U') + 60 * 60);
392:         } while ($timeFrom->format('G') + $timeWindow->format('G') <= $timeTo->format('G'));
393:         $result .= '</select>';
394:         
395:         return $result;
396:     }
397:     
398:     
399:     /**
400:      * <p>Normalizes DPD times to Unix timestamps.</p>
401:      * <p>For example 930 should be displayed as 09:30 and 9 should be displayed as 09:00</p>
402:      * @param string $input
403:      * @return int
404:      */
405:     protected function _normalizeTime($input) {
406:         if (strlen($input) === 1) {
407:             $input = '0'.$input .'00';
408:         }
409:         if (strlen($input) === 2) {
410:             $input = $input .'00';
411:         }
412:         if (strlen($input) === 3) {
413:             $input = '0'.$input;
414:         }
415:         $date = new DateTime();
416:         $this->setTimestamp($date, 0);
417: //        $date->setTimestamp(0);
418:         $date->setTimezone(new DateTimeZone('ETC/GMT+0'));
419:         $date->setTime($input[0].$input[1], $input[2].$input[3], 0);
420:         return $date;
421:     }
422:     
423:     
424:     
425: }
426: 
API documentation generated by ApiGen 2.8.0