Model.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. namespace Ipol\DPD\DB\Order;
  3. use \Ipol\DPD\Order as DpdOrder;
  4. use \Ipol\DPD\DB\Model as BaseModel;
  5. use \Ipol\DPD\Shipment;
  6. /**
  7. * Модель одной записи таблицы заказов
  8. */
  9. class Model extends BaseModel
  10. {
  11. const SERVICE_VARIANT_D = 'Д';
  12. const SERVICE_VARIANT_T = 'Т';
  13. /**
  14. * Отправление
  15. * @var \Ipol\DPD\Shipment
  16. */
  17. protected $shipment;
  18. /**
  19. * Возвращает список статусов и их описаний
  20. *
  21. * @return array
  22. */
  23. public static function StatusList()
  24. {
  25. return array(
  26. DpdOrder::STATUS_NEW => 'Новый заказ, еще не отправлялся в DPD',
  27. DpdOrder::STATUS_OK => 'Успешно создан',
  28. DpdOrder::STATUS_PENDING => 'Принят, но нуждается в ручной доработке сотрудником DPD',
  29. DpdOrder::STATUS_ERROR => 'Не принят, ошибка',
  30. DpdOrder::STATUS_CANCEL => 'Заказ отменен',
  31. DpdOrder::STATUS_CANCEL_PREV => 'Заказ отменен ранее',
  32. DpdOrder::STATUS_NOT_DONE => 'Заказ отменен в процессе доставки',
  33. DpdOrder::STATUS_DEPARTURE => 'Посылка находится на терминале приема отправления',
  34. DpdOrder::STATUS_TRANSIT => 'Посылка находится в пути (внутренняя перевозка DPD)',
  35. DpdOrder::STATUS_TRANSIT_TERMINAL => 'Посылка находится на транзитном терминале',
  36. DpdOrder::STATUS_ARRIVE => 'Посылка находится на терминале доставки',
  37. DpdOrder::STATUS_COURIER => 'Посылка выведена на доставку',
  38. DpdOrder::STATUS_DELIVERED => 'Посылка доставлена получателю',
  39. DpdOrder::STATUS_LOST => 'Посылка утеряна',
  40. DpdOrder::STATUS_PROBLEM => 'C посылкой возникла проблемная ситуация',
  41. DpdOrder::STATUS_RETURNED => 'Посылка возвращена с курьерской доставки',
  42. DpdOrder::STATUS_NEW_DPD => 'Оформлен новый заказ по инициативе DPD',
  43. DpdOrder::STATUS_NEW_CLIENT => 'Оформлен новый заказ по инициативе клиента',
  44. );
  45. }
  46. /**
  47. * Возвращает отправку
  48. *
  49. * @param bool $forced true - создает новый инстанс на основе полей записи
  50. *
  51. * @return \Ipol\DPD\Shipment
  52. */
  53. public function getShipment($forced = false)
  54. {
  55. if (is_null($this->shipment) || $forced) {
  56. $this->shipment = new Shipment($this->getTable()->getConfig());
  57. $this->shipment->setSender($this->senderLocation);
  58. $this->shipment->setReceiver($this->receiverLocation);
  59. $this->shipment->setPaymentMethod($this->personeTypeId, $this->paySystemId);
  60. $this->shipment->setItems($this->orderItems, $this->sumNpp);
  61. list($selfPickup, $selfDelivery) = array_values($this->getServiceVariant());
  62. $this->shipment->setSelfPickup($selfPickup);
  63. $this->shipment->setSelfDelivery($selfDelivery);
  64. if ($this->isCreated()) {
  65. $this->shipment->setWidth($this->dimensionWidth);
  66. $this->shipment->setHeight($this->dimensionHeight);
  67. $this->shipment->setLength($this->dimensionLength);
  68. $this->shipment->setWeight($this->cargoWeight);
  69. }
  70. }
  71. return $this->shipment;
  72. }
  73. /**
  74. * Ассоциирует внешнюю отправку с записью
  75. * Происходит заполнение полей записи на основе данных отправки
  76. *
  77. * @param \Ipol\DPD\Shipment $shipment
  78. *
  79. * @return self
  80. */
  81. public function setShipment(Shipment $shipment)
  82. {
  83. $this->shipment = $shipment;
  84. $this->senderLocation = $shipment->getSender()['ID'];
  85. $this->receiverLocation = $shipment->getReceiver()['ID'];
  86. $this->cargoWeight = $shipment->getWeight();
  87. $this->cargoVolume = $shipment->getVolume();
  88. $this->dimensionWidth = $shipment->getWidth();
  89. $this->dimensionWidth = $shipment->getHeight();
  90. $this->dimensionLength = $shipment->getLength();
  91. $this->personeTypeId = $shipment->getPaymentMethod()['PERSONE_TYPE_ID'];
  92. $this->paySystemId = $shipment->getPaymentMethod()['PAY_SYSTEM_ID'];
  93. $this->orderItems = $shipment->getItems();
  94. $this->price = $shipment->getPrice();
  95. $this->serviceVariant = [
  96. 'SELF_PICKUP' => $shipment->getSelfPickup(),
  97. 'SELF_DELIVERY' => $shipment->getSelfDelivery(),
  98. ];
  99. return $this;
  100. }
  101. /**
  102. * Сеттер св-ва ORDER_ITEMS
  103. *
  104. * @param array $items
  105. */
  106. public function setOrderItems($items)
  107. {
  108. $this->fields['ORDER_ITEMS'] = \serialize($items);
  109. return $this;
  110. }
  111. /**
  112. * Геттер св-ва ORDER_ITEMS
  113. *
  114. * @return array
  115. */
  116. public function getOrderItems()
  117. {
  118. return \unserialize($this->fields['ORDER_ITEMS']);
  119. }
  120. /**
  121. * Сеттер св-ва NPP
  122. *
  123. * @param float $npp
  124. *
  125. * @return self
  126. */
  127. public function setNpp($npp)
  128. {
  129. $this->fields['NPP'] = $npp;
  130. $this->fields['SUM_NPP'] = $npp == 'Y' ? $this->price : 0;
  131. return $this;
  132. }
  133. /**
  134. * Устанавливает вариант доставки
  135. *
  136. * @param string $variant
  137. *
  138. * @return self
  139. */
  140. public function setServiceVariant($variant)
  141. {
  142. $D = self::SERVICE_VARIANT_D;
  143. $T = self::SERVICE_VARIANT_T;
  144. if (is_string($variant) && preg_match('~^('. $D .'|'. $T .'){2}$~sUi', $variant)) {
  145. $this->fields['SERVICE_VARIANT'] = $variant;
  146. } else if (is_array($variant)) {
  147. $selfPickup = $variant['SELF_PICKUP'];
  148. $selfDelivery = $variant['SELF_DELIVERY'];
  149. $this->fields['SERVICE_VARIANT'] = ''
  150. . ($selfPickup ? $T : $D)
  151. . ($selfDelivery ? $T : $D)
  152. ;
  153. }
  154. return $this;
  155. }
  156. /**
  157. * Возвращает вариант доставки
  158. *
  159. * @return array
  160. */
  161. public function getServiceVariant()
  162. {
  163. $D = self::SERVICE_VARIANT_D;
  164. $T = self::SERVICE_VARIANT_T;
  165. return array(
  166. 'SELF_PICKUP' => mb_substr($this->fields['SERVICE_VARIANT'], 0, 1) == $T,
  167. 'SELF_DELIVERY' => mb_substr($this->fields['SERVICE_VARIANT'], 1, 1) == $T,
  168. );
  169. }
  170. /**
  171. * Возвращает флаг доставка от ТЕРМИНАЛА или ДВЕРИ
  172. *
  173. * @return bool
  174. */
  175. public function isSelfPickup()
  176. {
  177. $serviceVariant = $this->getServiceVariant();
  178. return $serviceVariant['SELF_PICKUP'];
  179. }
  180. /**
  181. * Возвращает флаг доставка до ТЕРМИНАЛА или ДВЕРИ
  182. *
  183. * @return bool
  184. */
  185. public function isSelfDelivery()
  186. {
  187. $serviceVariant = $this->getServiceVariant();
  188. return $serviceVariant['SELF_DELIVERY'];
  189. }
  190. /**
  191. * Возвращает текстовое описание статуса заказа
  192. *
  193. * @return string
  194. */
  195. public function getOrderStatusText()
  196. {
  197. $statusList = static::StatusList();
  198. $ret = $statusList[$this->orderStatus];
  199. if ($this->orderStatus == DpdOrder::STATUS_ERROR) {
  200. $ret .= ': '. $this->orderError;
  201. }
  202. return $ret;
  203. }
  204. /**
  205. * Возвращает ифнормацию о тарифе
  206. *
  207. * @param bool $forced пересоздать ли экземпляр отгрузки
  208. *
  209. * @return array
  210. */
  211. public function getTariffDelivery($forced = false)
  212. {
  213. return $this->getShipment($forced)->calculator()->calculateWithTariff($this->serviceCode, $this->currency);
  214. }
  215. /**
  216. * Возвращает стоимость доставки в заказе
  217. *
  218. * @return float
  219. */
  220. public function getActualPriceDelivery()
  221. {
  222. $tariff = $this->getTariffDelivery();
  223. if ($tariff) {
  224. return $tariff['COST'];
  225. }
  226. return false;
  227. }
  228. /**
  229. * Сеттер для номера заказа, попутно устанавливаем номер отправления
  230. *
  231. * @param $orderNum
  232. *
  233. * @return self
  234. */
  235. public function setOrderNum($orderNum)
  236. {
  237. $this->fields['ORDER_NUM'] = $orderNum;
  238. $this->fields['ORDER_DATE_CREATE'] = $orderNum ? date('Y-m-d H:i:s') : null;
  239. return $this;
  240. }
  241. /**
  242. * Сеттер для статуса заказа
  243. *
  244. * @param $orderStatus
  245. * @param $orderStatusDate
  246. *
  247. * @return self
  248. */
  249. public function setOrderStatus($orderStatus, $orderStatusDate = false)
  250. {
  251. if (empty($orderStatus)) {
  252. return;
  253. }
  254. if (!array_key_exists($orderStatus, self::StatusList())) {
  255. return;
  256. }
  257. $this->fields['ORDER_STATUS'] = $orderStatus;
  258. $this->fields['ORDER_DATE_STATUS'] = $orderStatusDate ?: date('Y-m-d H:i:s');
  259. if ($orderStatus == DpdOrder::STATUS_CANCEL) {
  260. $this->fields['ORDER_DATE_CANCEL'] = $orderStatusDate ?: date('Y-m-d H:i:s');
  261. }
  262. }
  263. /**
  264. * Возвращает флаг новый заказ
  265. *
  266. * @return bool
  267. */
  268. public function isNew()
  269. {
  270. return $this->fields['ORDER_STATUS'] == DpdOrder::STATUS_NEW;
  271. }
  272. /**
  273. * Проверяет отправлялся ли заказ в DPD
  274. *
  275. * @return bool
  276. */
  277. public function isCreated()
  278. {
  279. return $this->fields['ORDER_STATUS'] != DpdOrder::STATUS_NEW
  280. && $this->fields['ORDER_STATUS'] != DpdOrder::STATUS_CANCEL;
  281. }
  282. /**
  283. * Проверяет отправлялся ли заказ в DPD и был ли он там успешно создан
  284. *
  285. * @return bool
  286. */
  287. public function isDpdCreated()
  288. {
  289. return $this->isCreated() && !empty($this->fields['ORDER_NUM']);
  290. }
  291. /**
  292. * Возвращает инстанс для работы с внешним заказом
  293. *
  294. * @return \Ipol\DPD\Order;
  295. */
  296. public function dpd()
  297. {
  298. return new DpdOrder($this);
  299. }
  300. }