Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
orderbase.php
1<?php
8namespace Bitrix\Sale;
9
11use Bitrix\Main;
16
17Loc::loadMessages(__FILE__);
18
23abstract class OrderBase extends Internals\Entity
24{
26 protected $calculatedFields = null;
27
30
33
35 protected $discount = null;
36
38 protected $tax = null;
39
41 protected $internalId = 0;
42
44 protected $isNew = true;
45
47 protected $isSaveExecuting = false;
48
50 protected $isClone = false;
51
53 protected $isOnlyMathAction = null;
54
56 protected $isMeaningfulField = false;
57
59 protected $isStartField = null;
60
61
63 protected $calculateType = null;
64
68
74 protected function __construct(array $fields = array())
75 {
76 parent::__construct($fields);
77
78 $this->isNew = (empty($fields['ID']));
79 }
80
86 public function getInternalId()
87 {
88 static $idPool = 0;
89 if ($this->internalId == 0)
90 {
91 $idPool++;
92 $this->internalId = $idPool;
93 }
94
95 return $this->internalId;
96 }
97
103 public static function getAvailableFields()
104 {
105 $result = array(
106 "LID", "PERSON_TYPE_ID", "CANCELED", "DATE_CANCELED",
107 "EMP_CANCELED_ID", "REASON_CANCELED", "STATUS_ID", "DATE_STATUS", "EMP_STATUS_ID", "DEDUCTED",
108 "MARKED", "DATE_MARKED", "EMP_MARKED_ID", "REASON_MARKED",
109 "PRICE", "CURRENCY", "DISCOUNT_VALUE", "USER_ID",
110 "DATE_INSERT", "DATE_UPDATE", "USER_DESCRIPTION", "ADDITIONAL_INFO", "COMMENTS", "TAX_VALUE",
111 "STAT_GID", "RECURRING_ID", "LOCKED_BY", "IS_RECURRING",
112 "DATE_LOCK", "RECOUNT_FLAG", "AFFILIATE_ID", "DELIVERY_DOC_NUM", "DELIVERY_DOC_DATE", "UPDATED_1C",
113 "STORE_ID", "ORDER_TOPIC", "RESPONSIBLE_ID", "DATE_BILL", "DATE_PAY_BEFORE", "ACCOUNT_NUMBER",
114 "XML_ID", "ID_1C", "VERSION_1C", "VERSION", "EXTERNAL_ORDER", "COMPANY_ID", "IS_SYNC_B24"
115 );
116
117 return array_merge($result, static::getCalculatedFields());
118 }
119
125 protected static function getCalculatedFields()
126 {
127 return array(
128 'PRICE_WITHOUT_DISCOUNT',
129 'ORDER_WEIGHT',
130 'DISCOUNT_PRICE',
131 'BASE_PRICE_DELIVERY',
132
133 'DELIVERY_LOCATION',
134 'DELIVERY_LOCATION_ZIP',
135 'TAX_LOCATION',
136 'TAX_PRICE',
137
138 'VAT_RATE',
139 'VAT_VALUE',
140 'VAT_SUM',
141 'VAT_DELIVERY',
142 'USE_VAT',
143 );
144 }
145
149 public function isSaveRunning()
150 {
152 }
153
157 protected static function getMeaningfulFields()
158 {
159 return array('PERSON_TYPE_ID', 'PRICE');
160 }
161
168 private static function createOrderObject(array $fields = array())
169 {
170 $registry = Registry::getInstance(static::getRegistryType());
171 $orderClassName = $registry->getOrderClassName();
172
173 return new $orderClassName($fields);
174 }
175
179 public static function getRegistryEntity()
180 {
182 }
183
195 public static function create($siteId, $userId = null, $currency = null)
196 {
197 $fields = [
198 'CANCELED' => 'N',
199 'DEDUCTED' => 'N',
200 'ALLOW_DELIVERY' => 'N',
201 'PAYED' => 'N',
202 ];
203
204 $order = static::createOrderObject($fields);
205 $order->setFieldNoDemand('LID', $siteId);
206 if (intval($userId) > 0)
207 {
208 $order->setFieldNoDemand('USER_ID', $userId);
209 }
210
211 if ($currency == null)
212 {
213 $currency = Internals\SiteCurrencyTable::getSiteCurrency($siteId);
214 }
215
216 if ($currency == null)
217 {
218 $currency = Currency\CurrencyManager::getBaseCurrency();
219 }
220
221 $order->setFieldNoDemand('CURRENCY', $currency);
222 $order->setField('STATUS_ID', static::getInitialStatus());
223 $order->setFieldNoDemand('XML_ID', static::generateXmlId());
224
225 $order->calculateType = static::SALE_ORDER_CALC_TYPE_NEW;
226
227 return $order;
228 }
229
233 protected static function generateXmlId()
234 {
235 return uniqid('bx_');
236 }
237
245 public static function load($id)
246 {
247 $id = (int)$id;
248 if ($id <= 0)
249 {
250 throw new Main\ArgumentNullException("id");
251 }
252
253 $filter = [
254 'filter' => ['ID' => $id],
255 'select' => ['*'],
256 ];
257
258 $list = static::loadByFilter($filter);
259 if (!empty($list) && is_array($list))
260 {
261 return reset($list);
262 }
263
264 return null;
265 }
266
275 public static function loadByFilter(array $parameters)
276 {
277 $list = [];
278
279 $parameters = static::prepareParams($parameters);
280
282 $res = static::loadFromDb($parameters);
283 while($orderData = $res->fetch())
284 {
285 $order = static::createOrderObject($orderData);
286
287 $order->calculateType = static::SALE_ORDER_CALC_TYPE_CHANGE;
288 $list[] = $order;
289 }
290
291 return $list;
292 }
293
298 private static function prepareParams($parameters)
299 {
300 $result = array(
301 'select' => array('*')
302 );
303
304 if (isset($parameters['filter']))
305 {
306 $result['filter'] = $parameters['filter'];
307 }
308 if (isset($parameters['limit']))
309 {
310 $result['limit'] = $parameters['limit'];
311 }
312 if (isset($parameters['order']))
313 {
314 $result['order'] = $parameters['order'];
315 }
316 if (isset($parameters['offset']))
317 {
318 $result['offset'] = $parameters['offset'];
319 }
320 if (isset($parameters['runtime']))
321 {
322 $result['runtime'] = $parameters['runtime'];
323 }
324
325 return $result;
326 }
327
337 public static function loadByAccountNumber($value)
338 {
339 if (trim($value) == '')
340 {
341 throw new Main\ArgumentNullException("value");
342 }
343
344 $parameters = [
345 'filter' => ['=ACCOUNT_NUMBER' => $value],
346 'select' => ['*'],
347 ];
348
349 $list = static::loadByFilter($parameters);
350
351 return reset($list);
352 }
353
359 static protected function loadFromDb(array $parameters)
360 {
361 return static::getList($parameters);
362 }
363
371 public function setBasket(BasketBase $basket)
372 {
373 $result = self::appendBasket($basket);
374
375 if (!$this->isMathActionOnly())
376 {
378 $r = $basket->refreshData(['PRICE', 'QUANTITY', 'COUPONS']);
379 if (!$r->isSuccess())
380 {
381 $result->addErrors($r->getErrors());
382 return $result;
383 }
384 }
385
386 return $result;
387 }
388
397 public function appendBasket(BasketBase $basket)
398 {
399 if ($this->getId())
400 {
401 throw new Main\NotSupportedException();
402 }
403
404 $basket->setOrder($this);
405 $this->basketCollection = $basket;
406
407 return new Result();
408 }
409
415 public function getBasket()
416 {
417 if (!isset($this->basketCollection) || empty($this->basketCollection))
418 {
419 $this->basketCollection = $this->loadBasket();
420 }
421
423 }
424
432 protected function loadBasket()
433 {
434 if ($this->getId() > 0)
435 {
436 $registry = Registry::getInstance(static::getRegistryType());
438 $basketClassName = $registry->getBasketClassName();
439
440 return $basketClassName::loadItemsForOrder($this);
441 }
442
443 return null;
444 }
445
456 public function setField($name, $value)
457 {
458 if ($this->isCalculatedField($name))
459 {
460 $this->calculatedFields->set($name, $value);
461 return new Result();
462 }
463
464 return parent::setField($name, $value);
465 }
466
473 protected function checkValueBeforeSet($name, $value)
474 {
475 $result = parent::checkValueBeforeSet($name, $value);
476
477 if ($name === 'ACCOUNT_NUMBER')
478 {
479 $dbRes = static::getList([
480 'select' => ['ID'],
481 'filter' => ['=ACCOUNT_NUMBER' => $value]
482 ]);
483
484 if ($dbRes->fetch())
485 {
486 $result->addError(
487 new ResultError(
488 Loc::getMessage('SALE_ORDER_ACCOUNT_NUMBER_EXISTS')
489 )
490 );
491 }
492 }
493
494 return $result;
495 }
496
497 protected function normalizeValue($name, $value)
498 {
499 if ($this->isPriceField($name))
500 {
501 $value = PriceMaths::roundPrecision($value);
502 }
503
504 return parent::normalizeValue($name, $value);
505 }
506
517 public function setFieldNoDemand($name, $value)
518 {
519 if ($this->isCalculatedField($name))
520 {
521 $this->calculatedFields->set($name, $value);
522 return;
523 }
524
525 if (!$this->fields->isChanged("UPDATED_1C") && $name != 'UPDATED_1C')
526 {
527 $this->setField("UPDATED_1C", "N");
528 }
529
530 if ($this->isSaveExecuting === false)
531 {
532 if ($name === 'ID')
533 {
534 $this->isNew = false;
535 }
536 }
537
538 parent::setFieldNoDemand($name, $value);
539 }
540
547 public function getField($name)
548 {
549 if ($this->isCalculatedField($name))
550 {
551 return $this->calculatedFields->get($name);
552 }
553
554 return parent::getField($name);
555 }
556
567 public function initField($name, $value)
568 {
569 if ($this->isCalculatedField($name))
570 {
571 $this->calculatedFields->set($name, $value);
572 }
573
574 if ($name === 'ID')
575 {
576 $this->isNew = false;
577 }
578
579 parent::initField($name, $value);
580 }
581
589 public function getPropertyCollection()
590 {
591 if(empty($this->propertyCollection))
592 {
593 $this->propertyCollection = $this->loadPropertyCollection();
594 }
595
597 }
598
606 public function loadPropertyCollection()
607 {
608 $registry = Registry::getInstance(static::getRegistryType());
610 $propertyCollectionClassName = $registry->getPropertyValueCollectionClassName();
611
612 return $propertyCollectionClassName::load($this);
613 }
614
625 public function onPropertyValueCollectionModify($action, EntityPropertyValue $property, $name = null, $oldValue = null, $value = null)
626 {
627 return new Result();
628 }
629
639 public function refreshData()
640 {
641 $result = new Result();
642
643 $isStartField = $this->isStartField();
644
645 $this->calculateType = ($this->getId() > 0 ? static::SALE_ORDER_CALC_TYPE_REFRESH : static::SALE_ORDER_CALC_TYPE_NEW);
646
647 $this->resetData();
648
649 $this->refreshInternal();
650
651 if ($isStartField)
652 {
653 $hasMeaningfulFields = $this->hasMeaningfulField();
654
656 $r = $this->doFinalAction($hasMeaningfulFields);
657 if (!$r->isSuccess())
658 {
659 $result->addErrors($r->getErrors());
660 }
661 }
662
663 return $result;
664
665 }
666
673 protected function refreshInternal()
674 {
675 $result = new Result();
676
678 $basket = $this->getBasket();
679 if (!$basket)
680 {
681 return $result;
682 }
683
685 $r = $this->setField('PRICE', $basket->getPrice());
686 if (!$r->isSuccess())
687 {
688 $result->addErrors($r->getErrors());
689 return $result;
690 }
691
692 return $result;
693 }
694
700 public function getPersonTypeId()
701 {
702 return $this->getField('PERSON_TYPE_ID');
703 }
704
712 public function setPersonTypeId($personTypeId)
713 {
714 return $this->setField('PERSON_TYPE_ID', intval($personTypeId));
715 }
716
722 public function getPrice()
723 {
724 return floatval($this->getField('PRICE'));
725 }
726
732 public function getBasePrice(): float
733 {
734 $basket = $this->getBasket();
735 $taxPrice = !$this->isUsedVat() ? $this->getField('TAX_PRICE') : 0;
736
737 return $basket->getBasePrice() + $taxPrice;
738 }
739
745 public function getSumPaid()
746 {
747 return floatval($this->getField('SUM_PAID'));
748 }
749
753 public function getDeliveryPrice()
754 {
755 return floatval($this->getField('PRICE_DELIVERY'));
756 }
757
761 public function getDeliveryLocation()
762 {
763 return $this->getField('DELIVERY_LOCATION');
764 }
765
769 public function getTaxPrice()
770 {
771 return floatval($this->getField('TAX_PRICE'));
772 }
773
777 public function getTaxValue()
778 {
779 return floatval($this->getField('TAX_VALUE'));
780 }
781
787 public function getDiscountPrice()
788 {
789 return floatval($this->getField('DISCOUNT_PRICE'));
790 }
791
797 public function getCurrency()
798 {
799 return $this->getField('CURRENCY');
800 }
801
811 public function changeCurrency(string $currency): Main\Result
812 {
813 $result = new Main\Result();
814
815 if ($this->getCurrency() === $currency)
816 {
817 return $result;
818 }
819 elseif (empty($currency))
820 {
821 throw new ArgumentNullException('currency');
822 }
823
824 $this->setFieldNoDemand('CURRENCY', $currency);
825
826 foreach ($this->getBasket() as $basketItem)
827 {
832 $result->addErrors(
833 $basketItem->changeCurrency($currency)->getErrors()
834 );
835 }
836
837 return $result;
838 }
839
845 public function getUserId()
846 {
847 return $this->getField('USER_ID');
848 }
849
855 public function getSiteId()
856 {
857 return $this->getField('LID');
858 }
859
865 public function isUsedVat()
866 {
867 $useVat = $this->getField('USE_VAT');
868 if ($useVat === null)
869 {
870 $this->refreshVat();
871 }
872
873 return $this->getField('USE_VAT') === 'Y';
874 }
875
881 public function getVatRate()
882 {
883 $vatRate = $this->getField('VAT_RATE');
884 if ($vatRate === null && $this->getId() > 0)
885 {
886 $this->refreshVat();
887 return $this->getField('VAT_RATE');
888 }
889 return $vatRate;
890 }
891
897 public function getVatSum()
898 {
899 $vatSum = $this->getField('VAT_SUM');
900 if ($vatSum === null && $this->getId() > 0)
901 {
902 $this->refreshVat();
903 return $this->getField('VAT_SUM');
904 }
905 return $vatSum;
906 }
907
912 public function isMarked()
913 {
914 return $this->getField('MARKED') === "Y";
915 }
916
917 protected function isPriceField(string $name) : bool
918 {
919 return
920 $name === 'PRICE'
921 || $name === 'PRICE_DELIVERY'
922 || $name === 'SUM_PAID'
923 || $name === 'PRICE_PAYMENT'
924 || $name === 'DISCOUNT_VALUE'
925 ;
926 }
927
932 protected function resetVat()
933 {
934 $this->setFieldNoDemand('USE_VAT', 'N');
935 $this->setFieldNoDemand('VAT_RATE', 0);
936
937 $this->setFieldNoDemand('VAT_SUM', 0);
938 $this->setFieldNoDemand('VAT_DELIVERY', 0);
939 }
940
946 public function refreshVat()
947 {
948 $this->resetVat();
949
950 $vatInfo = $this->calculateVat();
951 if ($vatInfo && $vatInfo['VAT_RATE'] > 0)
952 {
953 return $this->applyCalculatedVat($vatInfo);
954 }
955
956 return new Result();
957 }
958
964 protected function calculateVat()
965 {
966 $result = array();
967
968 $basket = $this->getBasket();
969 if ($basket)
970 {
971 $result['VAT_RATE'] = $basket->getVatRate();
972 $result['VAT_SUM'] = $basket->getVatSum();
973 }
974
975 return $result;
976 }
977
982 private function applyCalculatedVat(array $vatInfo)
983 {
984 $result = new Result();
985
987 $r = $this->setField('USE_VAT', 'Y');
988 if (!$r->isSuccess())
989 {
990 $result->addErrors($r->getErrors());
991 }
992
994 $r = $this->setField('VAT_RATE', $vatInfo['VAT_RATE']);
995 if (!$r->isSuccess())
996 {
997 $result->addErrors($r->getErrors());
998 }
999
1001 $r = $this->setField('VAT_SUM', $vatInfo['VAT_SUM']);
1002 if (!$r->isSuccess())
1003 {
1004 $result->addErrors($r->getErrors());
1005 }
1006
1007 return $result;
1008 }
1009
1015 public function isShipped()
1016 {
1017 return $this->getField('DEDUCTED') === 'Y';
1018 }
1019
1025 public function isExternal()
1026 {
1027 return $this->getField('EXTERNAL_ORDER') == "Y";
1028 }
1029
1034 protected function isCalculatedField($field)
1035 {
1036 if ($this->calculatedFields == null )
1037 {
1038 $this->calculatedFields = new Internals\Fields();
1039 }
1040
1041 return (in_array($field, static::getCalculatedFields()));
1042 }
1043
1049 protected static function getInitialStatus()
1050 {
1051 $registry = Registry::getInstance(static::getRegistryType());
1052
1054 $orderStatus = $registry->getOrderStatusClassName();
1055 return $orderStatus::getInitialStatus();
1056 }
1057
1063 protected static function getFinalStatus()
1064 {
1065 $registry = Registry::getInstance(static::getRegistryType());
1066
1068 $orderStatus = $registry->getOrderStatusClassName();
1069 return $orderStatus::getFinalStatus();
1070 }
1071
1081 public function save()
1082 {
1083 if ($this->isSaveExecuting)
1084 {
1085 trigger_error("Order saving in recursion", E_USER_WARNING);
1086 }
1087
1088 $this->isSaveExecuting = true;
1089
1090 $result = new Result();
1091
1092 $id = $this->getId();
1093 $this->isNew = ($id == 0);
1094 $needUpdateDateInsert = $this->getDateInsert() === null;
1095
1096 $r = $this->callEventOnBeforeOrderSaved();
1097 if (!$r->isSuccess())
1098 {
1099 $this->isSaveExecuting = false;
1100 return $r;
1101 }
1102
1103 $r = $this->verify();
1104 if (!$r->isSuccess())
1105 {
1106 $result->addWarnings($r->getErrors());
1107 }
1108
1109 $r = $this->onBeforeSave();
1110 if (!$r->isSuccess())
1111 {
1112 $this->isSaveExecuting = false;
1113 return $r;
1114 }
1115 elseif ($r->hasWarnings())
1116 {
1117 $result->addWarnings($r->getWarnings());
1118 }
1119
1120 if ($id > 0)
1121 {
1122 $r = $this->update();
1123 }
1124 else
1125 {
1126 $r = $this->add();
1127 if ($r->getId() > 0)
1128 {
1129 $id = $r->getId();
1130 }
1131 }
1132
1133 if ($r->hasWarnings())
1134 {
1135 $result->addWarnings($r->getWarnings());
1136 }
1137
1138 if (!$r->isSuccess())
1139 {
1140 $this->isSaveExecuting = false;
1141 return $r;
1142 }
1143
1144 if ($id > 0)
1145 {
1146 $result->setId($id);
1147 }
1148
1149 $this->callEventOnSaleOrderEntitySaved();
1150
1151 $r = $this->saveEntities();
1152 if (!$r->isSuccess())
1153 {
1154 $result->addWarnings($r->getErrors());
1155 }
1156
1157 if ($r->hasWarnings())
1158 {
1159 $result->addWarnings($r->getWarnings());
1160 }
1161
1163 $discount = $this->getDiscount();
1164
1166 $r = $discount->save();
1167 if (!$r->isSuccess())
1168 {
1169 $result->addWarnings($r->getErrors());
1170 }
1171
1172 $r = $this->completeSaving($needUpdateDateInsert);
1173 if (!$r->isSuccess())
1174 {
1175 $result->addWarnings($r->getErrors());
1176 }
1177
1179 $this->callDelayedEvents();
1180
1181 $this->onAfterSave();
1182
1183 $this->isNew = false;
1184 $this->isSaveExecuting = false;
1185 $this->clearChanged();
1186
1187 return $result;
1188 }
1189
1193 protected function onAfterSave()
1194 {
1195 return new Result();
1196 }
1197
1203 protected function callDelayedEvents()
1204 {
1205 $registry = Registry::getInstance(static::getRegistryType());
1206 $notifyClassName = $registry->getNotifyClassName();
1207
1208 $eventList = Internals\EventsPool::getEvents($this->getInternalId());
1209 if ($eventList)
1210 {
1211 foreach ($eventList as $eventName => $eventData)
1212 {
1213 $event = new Main\Event('sale', $eventName, $eventData);
1214 $event->send();
1215
1216 $notifyClassName::callNotify($this, $eventName);
1217 }
1218
1219 Internals\EventsPool::resetEvents($this->getInternalId());
1220 }
1221
1222 $notifyClassName::callNotify($this, EventActions::EVENT_ON_ORDER_SAVED);
1223 }
1224
1231 protected function completeSaving($needUpdateDateInsert)
1232 {
1233 $result = new Result();
1234
1235 $currentDateTime = new Type\DateTime();
1236 $updateFields = ['RUNNING' => 'N'];
1237
1238 $changedFields = $this->fields->getChangedValues();
1239 if ($this->isNew
1240 || (
1241 $this->isChanged()
1242 && !array_key_exists('DATE_UPDATE', $changedFields)
1243 )
1244 )
1245 {
1246 $updateFields['DATE_UPDATE'] = $currentDateTime;
1247 }
1248
1249 if ($needUpdateDateInsert)
1250 {
1251 $updateFields['DATE_INSERT'] = $currentDateTime;
1252 }
1253
1254 $this->setFieldsNoDemand($updateFields);
1255 $r = static::updateInternal($this->getId(), $updateFields);
1256 if (!$r->isSuccess())
1257 {
1258 $result->addErrors($r->getErrors());
1259 }
1260
1261 return $result;
1262 }
1263
1272 protected function add()
1273 {
1274 global $USER;
1275
1276 $result = new Result();
1277
1278 $currentDateTime = new Type\DateTime();
1279
1280 if (!$this->getField('DATE_UPDATE'))
1281 {
1282 $this->setField('DATE_UPDATE', $currentDateTime);
1283 }
1284
1285 if (!$this->getField('DATE_INSERT'))
1286 {
1287 $this->setField('DATE_INSERT', $currentDateTime);
1288 }
1289
1290 $fields = $this->fields->getValues();
1291
1292 if (is_object($USER) && $USER->isAuthorized())
1293 {
1294 $fields['CREATED_BY'] = $USER->getID();
1295 $this->setFieldNoDemand('CREATED_BY', $fields['CREATED_BY']);
1296 }
1297
1298 if (array_key_exists('REASON_MARKED', $fields) && mb_strlen($fields['REASON_MARKED']) > 255)
1299 {
1300 $fields['REASON_MARKED'] = mb_substr($fields['REASON_MARKED'], 0, 255);
1301 }
1302
1303 $fields['RUNNING'] = 'Y';
1304
1305 $r = $this->addInternal($fields);
1306 if (!$r->isSuccess())
1307 {
1308 return $result->addErrors($r->getErrors());
1309 }
1310
1311 if ($resultData = $r->getData())
1312 {
1313 $result->setData($resultData);
1314 }
1315
1316 $id = $r->getId();
1317 $this->setFieldNoDemand('ID', $id);
1318 $result->setId($id);
1319
1320 $this->setAccountNumber();
1321
1322 return $result;
1323 }
1324
1330 protected function update()
1331 {
1332 $result = new Result();
1333
1334 $fields = $this->fields->getChangedValues();
1335
1336 if ($this->isChanged())
1337 {
1338 if (array_key_exists('DATE_UPDATE', $fields) && $fields['DATE_UPDATE'] === null)
1339 {
1340 unset($fields['DATE_UPDATE']);
1341 }
1342
1343 $fields['VERSION'] = intval($this->getField('VERSION')) + 1;
1344 $this->setFieldNoDemand('VERSION', $fields['VERSION']);
1345
1346 if (array_key_exists('REASON_MARKED', $fields) && mb_strlen($fields['REASON_MARKED']) > 255)
1347 {
1348 $fields['REASON_MARKED'] = mb_substr($fields['REASON_MARKED'], 0, 255);
1349 }
1350
1351 $r = static::updateInternal($this->getId(), $fields);
1352
1353 if (!$r->isSuccess())
1354 {
1355 return $result->addErrors($r->getErrors());
1356 }
1357
1358 if ($resultData = $r->getData())
1359 {
1360 $result->setData($resultData);
1361 }
1362 }
1363
1364 return $result;
1365 }
1366
1370 protected function callEventOnSaleOrderEntitySaved()
1371 {
1372 $oldEntityValues = $this->fields->getOriginalValues();
1373
1374 if (!empty($oldEntityValues))
1375 {
1376 $eventManager = Main\EventManager::getInstance();
1377 if ($eventsList = $eventManager->findEventHandlers('sale', 'OnSaleOrderEntitySaved'))
1378 {
1380 $event = new Main\Event('sale', 'OnSaleOrderEntitySaved', array(
1381 'ENTITY' => $this,
1382 'VALUES' => $oldEntityValues,
1383 ));
1384 $event->send();
1385 }
1386 }
1387 }
1388
1392 protected function callEventOnSaleOrderSaved()
1393 {
1394 $eventManager = Main\EventManager::getInstance();
1395 if ($eventsList = $eventManager->findEventHandlers('sale', EventActions::EVENT_ON_ORDER_SAVED))
1396 {
1397 $event = new Main\Event('sale', EventActions::EVENT_ON_ORDER_SAVED, array(
1398 'ENTITY' => $this,
1399 'IS_NEW' => $this->isNew,
1400 'IS_CHANGED' => $this->isChanged(),
1401 'VALUES' => $this->fields->getOriginalValues(),
1402 ));
1403 $event->send();
1404 }
1405 }
1406
1410 protected function callEventOnBeforeOrderSaved()
1411 {
1412 $result = new Result();
1413
1415 $oldEntityValues = $this->fields->getOriginalValues();
1416
1417 $eventManager = Main\EventManager::getInstance();
1418 if ($eventsList = $eventManager->findEventHandlers('sale', EventActions::EVENT_ON_ORDER_BEFORE_SAVED))
1419 {
1421 $event = new Main\Event('sale', EventActions::EVENT_ON_ORDER_BEFORE_SAVED, array(
1422 'ENTITY' => $this,
1423 'VALUES' => $oldEntityValues
1424 ));
1425 $event->send();
1426
1427 if ($event->getResults())
1428 {
1430 foreach($event->getResults() as $eventResult)
1431 {
1432 if($eventResult->getType() == Main\EventResult::ERROR)
1433 {
1434 $errorMsg = new ResultError(Main\Localization\Loc::getMessage('SALE_EVENT_ON_BEFORE_ORDER_SAVED_ERROR'), 'SALE_EVENT_ON_BEFORE_ORDER_SAVED_ERROR');
1435 if ($eventResultData = $eventResult->getParameters())
1436 {
1437 if (isset($eventResultData) && $eventResultData instanceof ResultError)
1438 {
1440 $errorMsg = $eventResultData;
1441 }
1442 }
1443
1444 $result->addError($errorMsg);
1445 }
1446 }
1447 }
1448 }
1449
1450 return $result;
1451 }
1452
1462 protected function saveEntities()
1463 {
1464 $result = new Result();
1465
1466 $r = $this->getBasket()->save();
1467 if (!$r->isSuccess())
1468 {
1469 $result->addWarnings($r->getErrors());
1470 }
1471
1472 $r = $this->getTax()->save();
1473 if (!$r->isSuccess())
1474 {
1475 $result->addWarnings($r->getErrors());
1476 }
1477
1478 $r = $this->getPropertyCollection()->save();
1479 if (!$r->isSuccess())
1480 {
1481 $result->addWarnings($r->getErrors());
1482 }
1483
1484 return $result;
1485 }
1486
1495 protected function setAccountNumber()
1496 {
1497 $accountNumber = Internals\AccountNumberGenerator::generateForOrder($this);
1498 if ($accountNumber !== false)
1499 {
1500 $this->setField('ACCOUNT_NUMBER', $accountNumber);
1501
1502 static::updateInternal($this->getId(), ['ACCOUNT_NUMBER' => $accountNumber]);
1503 }
1504 }
1505
1511 public function setVatSum($price)
1512 {
1513 $this->setField('VAT_SUM', $price);
1514 }
1515
1521 public function setVatDelivery($price)
1522 {
1523 $this->setField('VAT_DELIVERY', $price);
1524 }
1525
1531 public function getDateInsert()
1532 {
1533 return $this->getField('DATE_INSERT');
1534 }
1535
1541 public function getCalculateType()
1542 {
1543 return $this->calculateType;
1544 }
1545
1557 protected function onFieldModify($name, $oldValue, $value)
1558 {
1559 global $USER;
1560
1561 $result = new Result();
1562
1563 if ($name !== 'UPDATED_1C' && !$this->getFields()->isChanged('UPDATED_1C'))
1564 {
1565 $this->setField("UPDATED_1C", "N");
1566 }
1567
1568 if ($name == "PRICE")
1569 {
1571 $r = $this->refreshVat();
1572 if (!$r->isSuccess())
1573 {
1574 $result->addErrors($r->getErrors());
1575 return $result;
1576 }
1577 }
1578 elseif ($name == "CURRENCY")
1579 {
1580 throw new Main\NotImplementedException('field CURRENCY');
1581 }
1582 elseif ($name == "CANCELED")
1583 {
1584 $event = new Main\Event('sale', EventActions::EVENT_ON_BEFORE_ORDER_CANCELED, array(
1585 'ENTITY' => $this
1586 ));
1587 $event->send();
1588
1589 if ($event->getResults())
1590 {
1592 foreach($event->getResults() as $eventResult)
1593 {
1594 if($eventResult->getType() == Main\EventResult::ERROR)
1595 {
1596 $errorMsg = new ResultError(
1597 Main\Localization\Loc::getMessage('SALE_EVENT_ON_BEFORE_ORDER_CANCELED_ERROR'),
1598 'SALE_EVENT_ON_BEFORE_ORDER_CANCELED_ERROR'
1599 );
1600 if ($eventResultData = $eventResult->getParameters())
1601 {
1602 if (isset($eventResultData) && $eventResultData instanceof ResultError)
1603 {
1605 $errorMsg = $eventResultData;
1606 }
1607 }
1608
1609 $result->addError($errorMsg);
1610 }
1611 }
1612 }
1613
1614 if (!$result->isSuccess())
1615 {
1616 return $result;
1617 }
1618
1619 $r = $this->onOrderModify($name, $oldValue, $value);
1620 if (!$r->isSuccess())
1621 {
1622 $result->addErrors($r->getErrors());
1623 return $result;
1624 }
1625
1626 $this->setField('DATE_CANCELED', new Type\DateTime());
1627
1628 if (is_object($USER) && $USER->isAuthorized())
1629 {
1630 $this->setField('EMP_CANCELED_ID', $USER->getID());
1631 }
1632
1633 Internals\EventsPool::addEvent(
1634 $this->getInternalId(),
1636 array('ENTITY' => $this)
1637 );
1638
1639 Internals\EventsPool::addEvent(
1640 $this->getInternalId(),
1642 array('ENTITY' => $this)
1643 );
1644 }
1645 elseif ($name == "USER_ID")
1646 {
1647 throw new Main\NotImplementedException('field USER_ID');
1648 }
1649 elseif($name == "MARKED")
1650 {
1651 if ($oldValue != "Y")
1652 {
1653 $this->setField('DATE_MARKED', new Type\DateTime());
1654
1655 if (is_object($USER) && $USER->isAuthorized())
1656 {
1657 $this->setField('EMP_MARKED_ID', $USER->getID());
1658 }
1659 }
1660 elseif ($value == "N")
1661 {
1662 $this->setField('REASON_MARKED', '');
1663 }
1664 }
1665 elseif ($name == "STATUS_ID")
1666 {
1667 $event = new Main\Event('sale', EventActions::EVENT_ON_BEFORE_ORDER_STATUS_CHANGE, array(
1668 'ENTITY' => $this,
1669 'VALUE' => $value,
1670 'OLD_VALUE' => $oldValue,
1671 ));
1672 $event->send();
1673
1674 if ($event->getResults())
1675 {
1677 foreach($event->getResults() as $eventResult)
1678 {
1679 if($eventResult->getType() == Main\EventResult::ERROR)
1680 {
1681 $errorMsg = new ResultError(
1682 Main\Localization\Loc::getMessage('SALE_EVENT_ON_BEFORE_ORDER_STATUS_CHANGE_ERROR'),
1683 'SALE_EVENT_ON_BEFORE_ORDER_STATUS_CHANGE_ERROR'
1684 );
1685 if ($eventResultData = $eventResult->getParameters())
1686 {
1687 if (isset($eventResultData) && $eventResultData instanceof ResultError)
1688 {
1690 $errorMsg = $eventResultData;
1691 }
1692 }
1693
1694 $result->addError($errorMsg);
1695 }
1696 }
1697 }
1698
1699 if (!$result->isSuccess())
1700 {
1701 return $result;
1702 }
1703
1704 $this->setField('DATE_STATUS', new Type\DateTime());
1705
1706 if (is_object($USER) && $USER->isAuthorized())
1707 {
1708 $this->setField('EMP_STATUS_ID', $USER->GetID());
1709 }
1710
1711 Internals\EventsPool::addEvent($this->getInternalId(), EventActions::EVENT_ON_ORDER_STATUS_CHANGE, array(
1712 'ENTITY' => $this,
1713 'VALUE' => $value,
1714 'OLD_VALUE' => $oldValue,
1715 ));
1716
1717 Internals\EventsPool::addEvent($this->getInternalId(), EventActions::EVENT_ON_ORDER_STATUS_CHANGE_SEND_MAIL, array(
1718 'ENTITY' => $this,
1719 'VALUE' => $value,
1720 'OLD_VALUE' => $oldValue,
1721 ));
1722
1723 if ($this->isStatusChangedOnPay($value, $oldValue))
1724 {
1725 Internals\EventsPool::addEvent($this->getInternalId(), EventActions::EVENT_ON_ORDER_STATUS_ALLOW_PAY_CHANGE, array(
1726 'ENTITY' => $this,
1727 'VALUE' => $value,
1728 'OLD_VALUE' => $oldValue,
1729 ));
1730 }
1731 }
1732
1733 return $result;
1734 }
1735
1742 protected function onOrderModify($name, $oldValue, $value)
1743 {
1744 return new Result();
1745 }
1746
1760 public function onBasketModify($action, BasketItemBase $basketItem, $name = null, $oldValue = null, $value = null)
1761 {
1762 $result = new Result();
1763
1764 if ($action === EventActions::DELETE)
1765 {
1767 $r = $this->refreshVat();
1768 if (!$r->isSuccess())
1769 {
1770 $result->addErrors($r->getErrors());
1771 return $result;
1772 }
1773
1774 if ($tax = $this->getTax())
1775 {
1776 $tax->resetTaxList();
1777 }
1778
1780 $r = $this->refreshOrderPrice();
1781 if (!$r->isSuccess())
1782 {
1783 $result->addErrors($r->getErrors());
1784 }
1785
1786 return $result;
1787 }
1788 elseif ($action !== EventActions::UPDATE)
1789 {
1790 return $result;
1791 }
1792
1793 if ($name == "QUANTITY" || $name == "PRICE")
1794 {
1796 $r = $this->refreshOrderPrice();
1797 if (!$r->isSuccess())
1798 {
1799 $result->addErrors($r->getErrors());
1800 }
1801 }
1802 elseif ($name == "CURRENCY")
1803 {
1804 if ($value != $this->getField("CURRENCY"))
1805 {
1806 throw new Main\NotSupportedException("CURRENCY");
1807 }
1808 }
1809
1810 return $result;
1811 }
1812
1817 public function onBeforeBasketRefresh()
1818 {
1819 return new Result();
1820 }
1821
1826 public function onAfterBasketRefresh()
1827 {
1828 return new Result();
1829 }
1830
1836 public function getTax()
1837 {
1838 if ($this->tax === null)
1839 {
1840 $this->tax = $this->loadTax();
1841 }
1842 return $this->tax;
1843 }
1844
1852 public function isNew()
1853 {
1854 return $this->isNew;
1855 }
1856
1862 public function resetTax()
1863 {
1864 $this->setFieldNoDemand('TAX_PRICE', 0);
1865 $this->setFieldNoDemand('TAX_VALUE', 0);
1866 }
1867
1873 public function isChanged()
1874 {
1875 if (parent::isChanged())
1876 return true;
1877
1880 {
1881 if ($propertyCollection->isChanged())
1882 {
1883 return true;
1884 }
1885 }
1886
1888 if ($basket = $this->getBasket())
1889 {
1890 if ($basket->isChanged())
1891 {
1892 return true;
1893 }
1894
1895 }
1896
1897 return false;
1898 }
1899
1907 public function clearChanged()
1908 {
1909 parent::clearChanged();
1910
1911 if ($basket = $this->getBasket())
1912 {
1913 $basket->clearChanged();
1914 }
1915
1916 if ($property = $this->getPropertyCollection())
1917 {
1918 $property->clearChanged();
1919 }
1920
1921 }
1922
1928 public function isClone()
1929 {
1930 return $this->isClone;
1931 }
1932
1938 public function isPaid()
1939 {
1940 return $this->getField('PAYED') === 'Y';
1941 }
1942
1948 public function isAllowDelivery()
1949 {
1950 return $this->getField('ALLOW_DELIVERY') === 'Y';
1951 }
1952
1958 public function isDeducted()
1959 {
1960 return $this->getField('DEDUCTED') === 'Y';
1961 }
1962
1968 public function isCanceled()
1969 {
1970 return $this->getField('CANCELED') === 'Y';
1971 }
1972
1978 public function getHash()
1979 {
1981 $dateInsert = $this->getDateInsert()->setTimeZone(new \DateTimeZone("Europe/Moscow"));
1982 $timestamp = $dateInsert->getTimestamp();
1983 return md5(
1984 $this->getId().
1985 $timestamp.
1986 $this->getUserId().
1987 $this->getField('ACCOUNT_NUMBER')
1988 );
1989 }
1990
1996 public function verify()
1997 {
1998 $result = new Result();
1999
2001 if ($basket = $this->getBasket())
2002 {
2003 $r = $basket->verify();
2004 if (!$r->isSuccess())
2005 {
2006 $result->addErrors($r->getErrors());
2007 }
2008 }
2009
2012 {
2013 $r = $propertyCollection->verify();
2014 if (!$r->isSuccess())
2015 {
2016 $result->addErrors($r->getErrors());
2017 }
2018 }
2019
2021 if ($discounts = $this->getDiscount())
2022 {
2023 $r = $discounts->verify();
2024 if (!$r->isSuccess())
2025 {
2026 $result->addErrors($r->getErrors());
2027 }
2028 unset($r);
2029 }
2030 unset($discounts);
2031
2032 return $result;
2033 }
2034
2042 public static function getList(array $parameters = array())
2043 {
2044 throw new Main\NotImplementedException();
2045 }
2046
2052 public function getTaxLocation()
2053 {
2054 if ((string)$this->getField('TAX_LOCATION') === "")
2055 {
2057
2058 if ($property = $propertyCollection->getTaxLocation())
2059 {
2060 $this->setField('TAX_LOCATION', $property->getValue());
2061 }
2062
2063 }
2064
2065 return $this->getField('TAX_LOCATION');
2066 }
2067
2073 public function isMathActionOnly()
2074 {
2076 }
2077
2081 public function hasMeaningfulField()
2082 {
2084 }
2085
2091 public function clearStartField()
2092 {
2093 $this->isStartField = null;
2094 $this->isMeaningfulField = false;
2095 }
2096
2101 public function isStartField($isMeaningfulField = false)
2102 {
2103 if ($this->isStartField === null)
2104 {
2105 $this->isStartField = true;
2106 }
2107 else
2108 {
2109 $this->isStartField = false;
2110 }
2111
2112 if ($isMeaningfulField === true)
2113 {
2114 $this->isMeaningfulField = true;
2115 }
2116
2117 return $this->isStartField;
2118 }
2119
2127 public function setMathActionOnly($value = false)
2128 {
2129 $this->isOnlyMathAction = $value;
2130 }
2131
2141 public static function deleteNoDemand($id)
2142 {
2143 $result = new Result();
2144
2145 if (!static::isExists($id))
2146 {
2147 $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_ENTITY_NOT_FOUND'), 'SALE_ORDER_ENTITY_NOT_FOUND'));
2148 return $result;
2149 }
2150
2152 $deleteResult = static::deleteEntitiesNoDemand($id);
2153 if (!$deleteResult->isSuccess())
2154 {
2155 $result->addErrors($deleteResult->getErrors());
2156 return $result;
2157 }
2158
2159 $r = static::deleteInternal($id);
2160 if (!$r->isSuccess())
2161 $result->addErrors($r->getErrors());
2162
2163 static::deleteExternalEntities($id);
2164
2165 return $result;
2166 }
2167
2175 public static function delete($id)
2176 {
2177 $result = new Result();
2178
2179 $registry = Registry::getInstance(static::getRegistryType());
2181 $orderClassName = $registry->getOrderClassName();
2182
2183 if (!$order = $orderClassName::load($id))
2184 {
2185 $result->addError(new ResultError(Loc::getMessage('SALE_ORDER_ENTITY_NOT_FOUND'), 'SALE_ORDER_ENTITY_NOT_FOUND'));
2186 return $result;
2187 }
2188
2190 $notifyClassName = $registry->getNotifyClassName();
2191 $notifyClassName::setNotifyDisable(true);
2192
2194 $r = $order->setField('CANCELED', 'Y');
2195 if (!$r->isSuccess())
2196 {
2197 $result->addErrors($r->getErrors());
2198 return $result;
2199 }
2200
2201 $r = $order->save();
2202 if (!$r->isSuccess())
2203 {
2204 $result->addErrors($r->getErrors());
2205 return $result;
2206 }
2207
2208 static::deleteEntities($order);
2209
2210 $event = new Main\Event(
2211 'sale',
2213 array('ENTITY' => $order)
2214 );
2215 $event->send();
2216
2217 foreach ($event->getResults() as $eventResult)
2218 {
2219 $return = null;
2220 if ($eventResult->getType() == Main\EventResult::ERROR)
2221 {
2222 if ($eventResultData = $eventResult->getParameters())
2223 {
2224 if (isset($eventResultData) && $eventResultData instanceof ResultError)
2225 {
2227 $errorMsg = $eventResultData;
2228 }
2229 }
2230
2231 if (!isset($errorMsg))
2232 $errorMsg = new ResultError('EVENT_ORDER_DELETE_ERROR');
2233
2234 $result->addError($errorMsg);
2235 return $result;
2236 }
2237 }
2238
2240 $r = $order->save();
2241 if ($r->isSuccess())
2242 {
2244 $r = static::deleteInternal($id);
2245 if ($r->isSuccess())
2246 static::deleteExternalEntities($id);
2247 }
2248 else
2249 {
2250 $result->addErrors($r->getErrors());
2251 }
2252
2253 $notifyClassName::setNotifyDisable(false);
2254
2255 $event = new Main\Event(
2256 'sale',
2258 array('ENTITY' => $order, 'VALUE' => $r->isSuccess())
2259 );
2260 $event->send();
2261
2262 $result->addData(array('ORDER' => $order));
2263
2264 return $result;
2265 }
2266
2271 protected static function deleteEntities(OrderBase $order)
2272 {
2274 if ($basketCollection = $order->getBasket())
2275 {
2277 foreach ($basketCollection as $basketItem)
2278 {
2279 $basketItem->delete();
2280 }
2281 }
2282
2284 if ($propertyCollection = $order->getPropertyCollection())
2285 {
2287 foreach ($propertyCollection as $property)
2288 {
2289 $property->delete();
2290 }
2291 }
2292 }
2293
2299 protected static function isExists($id)
2300 {
2301 $dbRes = static::getList(array('filter' => array('ID' => $id)));
2302 if ($dbRes->fetch())
2303 return true;
2304
2305 return false;
2306 }
2307
2317 public function isAllowPay()
2318 {
2319 $registry = Registry::getInstance(static::getRegistryType());
2320
2322 $orderClassName = $registry->getOrderStatusClassName();
2323 return $orderClassName::isAllowPay($this->getField('STATUS_ID'));
2324 }
2325
2329 protected static function deleteExternalEntities($orderId)
2330 {
2331 return;
2332 }
2333
2338 protected static function deleteEntitiesNoDemand($orderId)
2339 {
2340 $registry = Registry::getInstance(static::getRegistryType());
2341
2343 $basketClassName = $registry->getBasketClassName();
2344 $r = $basketClassName::deleteNoDemand($orderId);
2345 if (!$r->isSuccess())
2346 {
2347 return $r;
2348 }
2349
2351 $propertyValueCollectionClassName = $registry->getPropertyValueCollectionClassName();
2352 $r = $propertyValueCollectionClassName::deleteNoDemand($orderId);
2353 if (!$r->isSuccess())
2354 {
2355 return $r;
2356 }
2357
2359 $orderDiscountClassName = $registry->getOrderDiscountClassName();
2360 $orderDiscountClassName::deleteByOrder($orderId);
2361
2362 return new Result();
2363 }
2364
2370 public function getDiscount()
2371 {
2372 if ($this->discount === null)
2373 {
2374 $this->discount = $this->loadDiscount();
2375 }
2376
2377 return $this->discount;
2378 }
2379
2385 protected function loadTax()
2386 {
2387 $registry = Registry::getInstance(static::getRegistryType());
2388
2390 $taxClassName = $registry->getTaxClassName();
2391 return $taxClassName::load($this);
2392 }
2393
2399 protected function loadDiscount()
2400 {
2401 $registry = Registry::getInstance(static::getRegistryType());
2402
2404 $discountClassName = $registry->getDiscountClassName();
2405 return $discountClassName::buildFromOrder($this);
2406 }
2407
2411 private function refreshOrderPrice()
2412 {
2413 return $this->setField("PRICE", $this->calculatePrice());
2414 }
2415
2419 protected function calculatePrice()
2420 {
2421 $basket = $this->getBasket();
2422 $taxPrice = !$this->isUsedVat() ? $this->getField('TAX_PRICE') : 0;
2423
2424 return $basket->getPrice() + $taxPrice;
2425 }
2426
2430 protected function onBeforeSave()
2431 {
2432 return new Result();
2433 }
2434
2441 public function doFinalAction($hasMeaningfulField = false)
2442 {
2443 $result = new Result();
2444
2445 $orderInternalId = $this->getInternalId();
2446
2447 $r = Internals\ActionEntity::runActions($orderInternalId);
2448 if (!$r->isSuccess())
2449 {
2450 $result->addErrors($r->getErrors());
2451 }
2452
2453 if (!$hasMeaningfulField)
2454 {
2455 $this->clearStartField();
2456 return $result;
2457 }
2458
2459
2460 if ($r->hasWarnings())
2461 {
2462 $result->addWarnings($r->getWarnings());
2463 }
2464
2465 $currentIsMathActionOnly = $this->isMathActionOnly();
2466
2467 $basket = $this->getBasket();
2468 if ($basket)
2469 {
2470 $this->setMathActionOnly(true);
2471
2472 $eventManager = Main\EventManager::getInstance();
2473 $eventsList = $eventManager->findEventHandlers('sale', 'OnBeforeSaleOrderFinalAction');
2474 if (!empty($eventsList))
2475 {
2476 $event = new Main\Event('sale', 'OnBeforeSaleOrderFinalAction', array(
2477 'ENTITY' => $this,
2478 'HAS_MEANINGFUL_FIELD' => $hasMeaningfulField,
2479 'BASKET' => $basket,
2480 ));
2481 $event->send();
2482
2483 if ($event->getResults())
2484 {
2486 foreach($event->getResults() as $eventResult)
2487 {
2488 if($eventResult->getType() == Main\EventResult::ERROR)
2489 {
2490 $errorMsg = new ResultError(
2491 Main\Localization\Loc::getMessage(
2492 'SALE_EVENT_ON_BEFORE_SALEORDER_FINAL_ACTION_ERROR'
2493 ),
2494 'SALE_EVENT_ON_BEFORE_SALEORDER_FINAL_ACTION_ERROR'
2495 );
2496
2497 $eventResultData = $eventResult->getParameters();
2498 if ($eventResultData)
2499 {
2500 if (isset($eventResultData) && $eventResultData instanceof ResultError)
2501 {
2503 $errorMsg = $eventResultData;
2504 }
2505 }
2506
2507 $result->addError($errorMsg);
2508 }
2509 }
2510 }
2511 }
2512
2513 if (!$result->isSuccess())
2514 {
2515 return $result;
2516 }
2517
2518 // discount
2519 $discount = $this->getDiscount();
2520 $r = $discount->calculate();
2521 if (!$r->isSuccess())
2522 {
2523// $this->clearStartField();
2524// $result->addErrors($r->getErrors());
2525// return $result;
2526 }
2527
2528 if ($r->isSuccess() && ($discountData = $r->getData()) && !empty($discountData) && is_array($discountData))
2529 {
2531 $r = $this->applyDiscount($discountData);
2532 if (!$r->isSuccess())
2533 {
2534 $result->addErrors($r->getErrors());
2535 return $result;
2536 }
2537 }
2538
2540 $tax = $this->getTax();
2542 $r = $tax->refreshData();
2543 if (!$r->isSuccess())
2544 {
2545 $result->addErrors($r->getErrors());
2546 return $result;
2547 }
2548
2549 $taxResult = $r->getData();
2550
2551 $taxChanged = false;
2552 if (isset($taxResult['TAX_PRICE']) && floatval($taxResult['TAX_PRICE']) >= 0)
2553 {
2554 if (!$this->isUsedVat())
2555 {
2556 $taxChanged = $this->getField('TAX_PRICE') !== $taxResult['TAX_PRICE'];
2557 if ($taxChanged)
2558 {
2559 $this->setField('TAX_PRICE', $taxResult['TAX_PRICE']);
2560 $this->refreshOrderPrice();
2561 }
2562 }
2563
2564 }
2565
2566 if (array_key_exists('VAT_SUM', $taxResult))
2567 {
2568 if ($this->isUsedVat())
2569 {
2570 $this->setField('VAT_SUM', $taxResult['VAT_SUM']);
2571 }
2572 }
2573
2574 if ($taxChanged || $this->isUsedVat())
2575 {
2576 $taxValue = $this->isUsedVat()? $this->getVatSum() : $this->getField('TAX_PRICE');
2577 if (floatval($taxValue) != floatval($this->getField('TAX_VALUE')))
2578 {
2579 $this->setField('TAX_VALUE', floatval($taxValue));
2580 }
2581 }
2582
2583 }
2584
2585 if (!$currentIsMathActionOnly)
2586 $this->setMathActionOnly(false);
2587
2588 $this->clearStartField();
2589
2590 $eventManager = Main\EventManager::getInstance();
2591 if ($eventsList = $eventManager->findEventHandlers('sale', 'OnAfterSaleOrderFinalAction'))
2592 {
2593 $event = new Main\Event(
2594 'sale',
2595 'OnAfterSaleOrderFinalAction',
2596 array('ENTITY' => $this)
2597 );
2598 $event->send();
2599 }
2600
2601 return $result;
2602 }
2603
2613 public function applyDiscount(array $data)
2614 {
2615 if (!empty($data['BASKET_ITEMS']) && is_array($data['BASKET_ITEMS']))
2616 {
2618 $basket = $this->getBasket();
2619 $basketResult = $basket->applyDiscount($data['BASKET_ITEMS']);
2620 if (!$basketResult->isSuccess())
2621 return $basketResult;
2622 unset($basketResult, $basket);
2623
2624 $this->refreshOrderPrice();
2625 }
2626
2627 return new Result();
2628 }
2629
2635 protected function setReasonMarked($value)
2636 {
2637 $result = new Result();
2638
2639 if (!empty($value))
2640 {
2641 $orderReasonMarked = $this->getField('REASON_MARKED');
2642 if (is_array($value))
2643 {
2644 $newOrderReasonMarked = '';
2645
2646 foreach ($value as $err)
2647 {
2648 $newOrderReasonMarked .= (strval($newOrderReasonMarked) != '' ? "\n" : "") . $err;
2649 }
2650 }
2651 else
2652 {
2653 $newOrderReasonMarked = $value;
2654 }
2655
2657 $r = $this->setField('REASON_MARKED', $orderReasonMarked. (strval($orderReasonMarked) != '' ? "\n" : ""). $newOrderReasonMarked);
2658 if (!$r->isSuccess())
2659 {
2660 $result->addErrors($r->getErrors());
2661 }
2662 }
2663
2664 return $result;
2665 }
2666
2675 public function resetData($select = array('PRICE'))
2676 {
2677 if (in_array('PRICE', $select))
2678 {
2679 $this->setField('PRICE', 0);
2680 }
2681
2682 if (in_array('PRICE_DELIVERY', $select))
2683 {
2684 $this->setField('PRICE_DELIVERY', 0);
2685 }
2686 }
2687
2697 protected function isStatusChangedOnPay($value, $oldValue)
2698 {
2699 $registry = Registry::getInstance(static::getRegistryType());
2700
2702 $orderStatus = $registry->getOrderStatusClassName();
2703
2704 $allowPayStatus = $orderStatus::getAllowPayStatusList();
2705 $disallowPayStatus = $orderStatus::getDisallowPayStatusList();
2706
2707 return !empty($disallowPayStatus)
2708 && in_array($oldValue, $disallowPayStatus)
2709 && !empty($allowPayStatus)
2710 && in_array($value, $allowPayStatus);
2711 }
2712
2721 public function createClone()
2722 {
2723 $cloneEntity = new \SplObjectStorage();
2724
2726 $orderClone = clone $this;
2727 $orderClone->isClone = true;
2728
2730 if ($fields = $this->fields)
2731 {
2732 $orderClone->fields = $fields->createClone($cloneEntity);
2733 }
2734
2736 if ($calculatedFields = $this->calculatedFields)
2737 {
2738 $orderClone->calculatedFields = $calculatedFields->createClone($cloneEntity);
2739 }
2740
2741 if (!$cloneEntity->contains($this))
2742 {
2743 $cloneEntity[$this] = $orderClone;
2744 }
2745
2746 $this->cloneEntities($cloneEntity);
2747
2748 return $orderClone;
2749 }
2750
2757 protected function cloneEntities(\SplObjectStorage $cloneEntity)
2758 {
2759 if (!$cloneEntity->contains($this))
2760 {
2761 throw new Main\SystemException();
2762 }
2763
2764 $orderClone = $cloneEntity[$this];
2765
2767 if ($basket = $this->getBasket())
2768 {
2769 $orderClone->basketCollection = $basket->createClone($cloneEntity);
2770 }
2771
2774 {
2775 $orderClone->propertyCollection = $propertyCollection->createClone($cloneEntity);
2776 }
2777
2778 if ($tax = $this->getTax())
2779 {
2780 $orderClone->tax = $tax->createClone($cloneEntity);
2781 }
2782
2783 if ($discount = $this->getDiscount())
2784 {
2785 $orderClone->discount = $discount->createClone($cloneEntity);
2786 }
2787 }
2788
2794 abstract protected function addInternal(array $data);
2795
2802 protected static function updateInternal($primary, array $data)
2803 {
2804 throw new Main\NotImplementedException();
2805 }
2806
2812 protected static function deleteInternal($primary)
2813 {
2814 throw new Main\NotImplementedException();
2815 }
2816
2822 public static function getUfId()
2823 {
2824 return null;
2825 }
2826
2832 public static function getSettableFields()
2833 {
2834 return static::getAvailableFields();
2835 }
2836
2842 public static function getEntityEventName()
2843 {
2844 return 'SaleOrder';
2845 }
2846
2847 public function toArray() : array
2848 {
2849 $result = parent::toArray();
2850
2851 $result['BASKET_ITEMS'] = $this->getBasket()->toArray();
2852 $result['PROPERTIES'] = $this->getPropertyCollection()->toArray();
2853
2854 return $result;
2855 }
2856}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
refreshData($select=array(), BasketItemBase $refreshItem=null)
setOrder(OrderBase $order)
const EVENT_ON_ORDER_STATUS_CHANGE_SEND_MAIL
const EVENT_ON_ORDER_STATUS_ALLOW_PAY_CHANGE
setMathActionOnly($value=false)
onOrderModify($name, $oldValue, $value)
checkValueBeforeSet($name, $value)
onPropertyValueCollectionModify($action, EntityPropertyValue $property, $name=null, $oldValue=null, $value=null)
static getMeaningfulFields()
static deleteExternalEntities($orderId)
static getCalculatedFields()
static create($siteId, $userId=null, $currency=null)
static getList(array $parameters=array())
static updateInternal($primary, array $data)
initField($name, $value)
isStartField($isMeaningfulField=false)
static loadFromDb(array $parameters)
const SALE_ORDER_CALC_TYPE_CHANGE
Definition orderbase.php:66
resetData($select=array('PRICE'))
static getAvailableFields()
const SALE_ORDER_CALC_TYPE_REFRESH
Definition orderbase.php:67
__construct(array $fields=array())
Definition orderbase.php:74
isPriceField(string $name)
addInternal(array $data)
setPersonTypeId($personTypeId)
setFieldNoDemand($name, $value)
static deleteInternal($primary)
setField($name, $value)
appendBasket(BasketBase $basket)
normalizeValue($name, $value)
completeSaving($needUpdateDateInsert)
static loadByAccountNumber($value)
static roundPrecision($value)
static getInstance($type)
Definition registry.php:183