Bitrix-D7  20.5.0
orderhistory.php
См. документацию.
1 <?php
2 
3 
4 namespace Bitrix\Sale;
5 
6 
7 use Bitrix\Main;
10 
12 {
13  protected static $pool = array();
14  protected static $poolFields = array();
15 
16  const SALE_ORDER_HISTORY_UPDATE = 'UPDATE';
17 
21 
22  const FIELD_TYPE_NAME = 'NAME';
23  const FIELD_TYPE_TYPE = 'TYPE';
24 
27 
30 
31  protected function __construct()
32  {
33 
34  }
35 
36  /**
37  * @param string $entityName
38  * @param int $orderId
39  * @param string $field
40  * @param null|string $oldValue
41  * @param null|string $value
42  * @param int $id
43  * @param $entity
44  * @param array $fields
45  */
46  public static function addField($entityName, $orderId, $field, $oldValue = null, $value = null, $id = null, $entity = null, array $fields = array())
47  {
48  if ($field == "ID")
49  return;
50 
51  if ($value !== null && static::isDate($value))
52  {
53  $value = $value->toString();
54  }
55 
56  if ($oldValue !== null && static::isDate($oldValue))
57  {
58  $oldValue = $oldValue->toString();
59  }
60 
61  if (!empty($fields))
62  {
63  foreach($fields as $fieldName => $fieldValue)
64  {
65  if (static::isDate($fieldValue))
66  {
67  $fields[$fieldName] = $fieldValue->toString();
68  }
69  }
70  }
71 
72  static::$pool[$entityName][$orderId][$id][$field][] = array(
73  'RECORD_TYPE' => static::SALE_ORDER_HISTORY_RECORD_TYPE_FIELD,
74  'ENTITY_NAME' => $entityName,
75  'ENTITY' => $entity,
76  'ORDER_ID' => $orderId,
77  'ID' => $id,
78  'NAME' => $field,
79  'OLD_VALUE' => $oldValue,
80  'VALUE' => $value,
81  'DATA' => $fields
82  );
83  }
84 
85  /**
86  * @param $entityName
87  * @param $orderId
88  * @param $type
89  * @param null $id
90  * @param null $entity
91  * @param array $fields
92  * @param null $level
93  *
94  * @throws Main\ArgumentNullException
95  * @throws Main\ArgumentOutOfRangeException
96  */
97  public static function addAction($entityName, $orderId, $type, $id = null, $entity = null, array $fields = array(), $level = null)
98  {
99  if ($level === null)
100  {
101  $level = static::SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_0;
102  }
103 
104  if (!static::checkActionLogLevel($level))
105  return;
106 
107  static::$pool[$entityName][$orderId][$id][$type][] = array(
108  'RECORD_TYPE' => static::SALE_ORDER_HISTORY_RECORD_TYPE_ACTION,
109  'ENTITY_NAME' => $entityName,
110  'ENTITY' => $entity,
111  'ID' => $id,
112  'TYPE' => $type,
113  'DATA' => $fields
114  );
115  }
116 
117  /**
118  * @param $entityName
119  * @param $orderId
120  * @param null|int $id
121  * @return bool
122  */
123  public static function collectEntityFields($entityName, $orderId, $id = null)
124  {
125  if (!$poolEntity = static::getPoolByEntity($entityName, $orderId))
126  {
127  return false;
128  }
129 
130  if ($id !== null)
131  {
132  $found = false;
133  foreach ($poolEntity as $entityId => $fieldValue)
134  {
135  if ($entityId == $id)
136  {
137  $found = true;
138  break;
139  }
140  }
141 
142  if (!$found)
143  return false;
144  }
145 
146  foreach ($poolEntity as $entityId => $fieldValue)
147  {
148  if ($id !== null && $entityId != $id)
149  continue;
150 
151  $entity = null;
152 
153  $dataFields = array();
154  $oldFields = array();
155  $fields = array();
156 
157  foreach ($fieldValue as $dataList)
158  {
159  foreach ($dataList as $key => $data)
160  {
161  if ($data['RECORD_TYPE'] == static::SALE_ORDER_HISTORY_RECORD_TYPE_ACTION
162  || $data['RECORD_TYPE'] == static::SALE_ORDER_HISTORY_RECORD_TYPE_DEBUG)
163  {
164  static::addRecord(
165  $entityName,
166  $orderId,
167  $data['TYPE'],
168  $data['ID'],
169  $data['ENTITY'],
170  static::prepareDataForAdd($entityName, $data['TYPE'], $data['ENTITY'], $data['DATA'])
171  );
172  unset(static::$pool[$entityName][$orderId][$data['ID']][$data['TYPE']][$key]);
173 
174  if (empty(static::$pool[$entityName][$orderId][$data['ID']][$data['TYPE']]))
175  unset(static::$pool[$entityName][$orderId][$data['ID']][$data['TYPE']]);
176 
177  continue;
178  }
179 
180  $value = $data['VALUE'];
181  $oldValue = $data['OLD_VALUE'];
182 
183  if (static::isDate($value))
184  $value = static::convertDateField($value);
185 
186  if (static::isDate($oldValue))
187  $oldValue = static::convertDateField($oldValue);
188 
189  $oldFields[$data['NAME']] = $oldValue;
190  $fields[$data['NAME']] = $value;
191 
192  if (!empty($data['DATA']) && is_array($data['DATA']))
193  {
194  $dataFields = array_merge($dataFields, $data['DATA']);
195  }
196 
197  $dataType = static::FIELD_TYPE_TYPE;
198  if (isset($data['RECORD_TYPE']) && $data['RECORD_TYPE'] == static::SALE_ORDER_HISTORY_RECORD_TYPE_FIELD)
199  {
200  $dataType = static::FIELD_TYPE_NAME;
201  }
202 
203  if (isset($data[$dataType]))
204  {
205  unset(static::$pool[$entityName][$orderId][$data['ID']][$data[$dataType]][$key]);
206 
207  if (empty(static::$pool[$entityName][$orderId][$data['ID']][$data[$dataType]]))
208  unset(static::$pool[$entityName][$orderId][$data['ID']][$data[$dataType]]);
209  }
210 
211  if ($entity === null && array_key_exists('ENTITY', $data))
212  {
213  $entity = $data['ENTITY'];
214  }
215 
216  }
217 
218  }
219 
220  if ($entityName === "") // for order
221  {
222  if (isset($fields["ID"]))
223  unset($fields["ID"]);
224  }
225 
226  foreach ($fields as $key => $val)
227  {
228  if (is_array($val))
229  {
230  continue;
231  }
232 
233  if (!array_key_exists($key, $oldFields)
234  || (
235  array_key_exists($key, $oldFields)
236  && $val <> '' && $val != $oldFields[$key]
237  )
238  )
239  {
240  $arRecord = \CSaleOrderChange::MakeRecordFromField($key, $dataFields, $entityName, $entity);
241  if ($arRecord)
242  {
243  $result = $arRecord["DATA"];
244  foreach ($arRecord["DATA"] as $fieldKey => $fieldValue)
245  {
246  if (!isset($result['OLD_'.$fieldKey]) && isset($dataFields['OLD_'.$fieldKey]))
247  {
248  $result['OLD_'.$fieldKey] = TruncateText($dataFields['OLD_'.$key], 128);
249  }
250  }
251 
252  static::addRecord(
253  $entityName,
254  $orderId,
255  $arRecord["TYPE"],
256  $entityId,
257  $entity,
258  static::prepareDataForAdd($entityName, $arRecord["TYPE"], $entity, $result)
259  );
260  }
261  }
262  }
263 
264  if (empty(static::$pool[$entityName][$orderId][$entityId]))
265  unset(static::$pool[$entityName][$orderId][$entityId]);
266  }
267 
268  if (empty(static::$pool[$entityName][$orderId]))
269  unset(static::$pool[$entityName][$orderId]);
270 
271  if (empty(static::$pool[$entityName]))
272  unset(static::$pool[$entityName]);
273 
274  return true;
275  }
276 
277  /**
278  * @param $entity
279  * @param $orderId
280  * @return bool|array
281  */
282  protected static function getPoolByEntity($entity, $orderId)
283  {
284  if (empty(static::$pool[$entity])
285  || empty(static::$pool[$entity][$orderId])
286  || !is_array(static::$pool[$entity][$orderId]))
287  {
288  return false;
289  }
290 
291  return static::$pool[$entity][$orderId];
292  }
293 
294  /**
295  * @param $entityName
296  * @param $type
297  * @param Entity $entity
298  * @param array $data
299  * @return array
300  */
301  protected static function prepareDataForAdd($entityName, $type, $entity = null, array $data = array())
302  {
303  if ($entity !== null
304  && ($operationType = static::getOperationType($entityName, $type))
305  && (!empty($operationType["DATA_FIELDS"]) && is_array($operationType["DATA_FIELDS"]))
306  )
307  {
308  foreach ($operationType["DATA_FIELDS"] as $fieldName)
309  {
310  if (!array_key_exists($fieldName, $data) && ($value = $entity->getField($fieldName)))
311  {
312  $data[$fieldName] = TruncateText($value, 128);
313  }
314  }
315  }
316 
317  return $data;
318  }
319 
320  /**
321  * @param $entityName
322  * @param $orderId
323  * @param $type
324  * @param null $id
325  * @param null|Entity $entity
326  * @param array $data
327  */
328  protected static function addRecord($entityName, $orderId, $type, $id = null, $entity = null, array $data = array())
329  {
330  global $USER;
331  $userId = (is_object($USER)) ? intval($USER->GetID()) : 0;
332 
333  $fields = array(
334  "ORDER_ID" => intval($orderId),
335  "TYPE" => $type,
336  "DATA" => (is_array($data) ? serialize($data) : $data),
337  "USER_ID" => $userId,
338  "ENTITY" => $entityName,
339  "ENTITY_ID" => $id,
340  );
341 
342  static::addInternal($fields);
343  }
344 
345  /**
346  * @param $fields
347  * @return Main\Entity\AddResult
348  * @throws \Exception
349  */
350  protected static function addInternal($fields)
351  {
352  return OrderChangeTable::add($fields);
353  }
354 
355  /**
356  * @param $entityName
357  * @param $type
358  *
359  * @return bool
360  */
361  protected static function getOperationType($entityName, $type)
362  {
363  if (!empty(\CSaleOrderChangeFormat::$operationTypes)
364  && !empty(\CSaleOrderChangeFormat::$operationTypes[$type])
365  )
366  {
367  if (!empty(\CSaleOrderChangeFormat::$operationTypes[$type]['ENTITY'])
368  && $entityName == \CSaleOrderChangeFormat::$operationTypes[$type]['ENTITY'])
369  {
370  return \CSaleOrderChangeFormat::$operationTypes[$type];
371  }
372  }
373 
374  return false;
375  }
376 
377  /**
378  * @param $value
379  * @return bool
380  */
381  private static function isDate($value)
382  {
383  return ($value instanceof Main\Type\DateTime) || ($value instanceof Main\Type\Date);
384  }
385 
386  /**
387  * @param $value
388  * @return string
389  */
390  private static function convertDateField($value)
391  {
392  if (($value instanceof Main\Type\DateTime)
393  || ($value instanceof Main\Type\Date))
394  {
395  return $value->toString();
396  }
397 
398  return $value;
399  }
400 
401  /**
402  * @param $id
403  * @return bool
404  * @throws Main\ArgumentException
405  * @throws Main\ObjectPropertyException
406  * @throws Main\SystemException
407  * @throws \Exception
408  */
409  public static function deleteByOrderId($id)
410  {
411  if (intval($id) <= 0)
412  return false;
413 
414  $dbRes = static::getList(array(
415  'select' => array('ID'),
416  'filter' => array('=ORDER_ID' => $id)
417  ));
418 
419  while ($data = $dbRes->fetch())
420  {
421  static::deleteInternal($data['ID']);
422  }
423 
424  return true;
425  }
426 
427  /**
428  * @param array $parameters
429  * @return Main\DB\Result
430  * @throws Main\ArgumentException
431  * @throws Main\ObjectPropertyException
432  * @throws Main\SystemException
433  */
434  protected static function getList(array $parameters = array())
435  {
436  return OrderChangeTable::getList($parameters);
437  }
438 
439  /**
440  * @param $primary
441  * @return Main\Entity\DeleteResult
442  * @throws \Exception
443  */
444  protected static function deleteInternal($primary)
445  {
446  return OrderChangeTable::delete($primary);
447  }
448 
449  /**
450  * @param $entityName
451  * @param $orderId
452  * @param $type
453  * @param null $id
454  * @param null $entity
455  * @param array $fields
456  * @param null $level
457  *
458  * @throws Main\ArgumentNullException
459  * @throws Main\ArgumentOutOfRangeException
460  */
461  public static function addLog($entityName, $orderId, $type, $id = null, $entity = null, array $fields = array(), $level = null)
462  {
463  if ($level === null)
464  {
465  $level = static::SALE_ORDER_HISTORY_LOG_LEVEL_0;
466  }
467 
468  if (!static::checkLogLevel($level))
469  return;
470 
471  if (!empty($fields))
472  {
473  foreach($fields as $fieldName => $fieldValue)
474  {
475  if (static::isDate($fieldValue))
476  {
477  $fields[$fieldName] = $fieldValue->toString();
478  }
479  }
480  }
481 
482  static::$pool[$entityName][$orderId][$id][$type][] = array(
483  'RECORD_TYPE' => static::SALE_ORDER_HISTORY_RECORD_TYPE_DEBUG,
484  'ENTITY_NAME' => $entityName,
485  'ENTITY' => $entity,
486  'ID' => $id,
487  'TYPE' => $type,
488  'DATA' => $fields,
489  'LEVEL' => $level
490  );
491  }
492 
493  /**
494  * @param $level
495  *
496  * @return bool
497  * @throws Main\ArgumentNullException
498  * @throws Main\ArgumentOutOfRangeException
499  */
500  public static function checkLogLevel($level)
501  {
502  $orderHistoryLogLevel = Main\Config\Option::get('sale', 'order_history_log_level', static::SALE_ORDER_HISTORY_LOG_LEVEL_0);
503 
504  if ($level > $orderHistoryLogLevel)
505  return false;
506 
507  return true;
508  }
509 
510  /**
511  * @param $level
512  *
513  * @return bool
514  * @throws Main\ArgumentNullException
515  * @throws Main\ArgumentOutOfRangeException
516  */
517  public static function checkActionLogLevel($level)
518  {
519  $orderHistoryActionLogLevel = Main\Config\Option::get(
520  'sale',
521  'order_history_action_log_level',
522  static::SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_0
523  );
524 
525  if ($level > $orderHistoryActionLogLevel)
526  return false;
527 
528  return true;
529  }
530 
531  /**
532  * @param $days
533  * @param null $limit
534  * @return bool
535  * @throws Main\ArgumentException
536  * @throws Main\ObjectException
537  * @throws Main\ObjectPropertyException
538  * @throws Main\SystemException
539  * @throws \Exception
540  */
541  protected static function deleteOldInternal($days, $limit = null)
542  {
543  $days = (int)($days);
544 
545  if ($days <= 0)
546  return false;
547 
548  $expired = new Main\Type\DateTime();
549  $expired->add('-'.$days.' days');
550 
551  $parameters = array(
552  'filter' => array('<DATE_CREATE' => $expired->toString())
553  );
554 
555  if ($limit > 0)
556  {
557  $parameters['limit'] = $limit;
558  }
559 
560  $dbRes = static::getList($parameters);
561  while ($data = $dbRes->fetch())
562  {
563  static::deleteInternal($data['ID']);
564  }
565 
566  return true;
567  }
568 
569  /**
570  * Delete old records on an agent
571  *
572  * @param $days
573  * @param null $hitLimit
574  * @return string
575  * @throws Main\ArgumentException
576  * @throws Main\ObjectException
577  * @throws Main\ObjectPropertyException
578  * @throws Main\SystemException
579  * @throws \Exception
580  */
581  public static function deleteOldAgent($days, $hitLimit = null)
582  {
583  $calledClass = '\\'.static::class;
584 
585  $days = (int)$days;
586 
587  static::deleteOldInternal($days, $hitLimit);
588 
589  if ($days)
590  {
591  $expired = new Main\Type\DateTime();
592  $expired->add("-$days days");
593  $dbRes = static::getList(array(
594  'filter' => array('<DATE_CREATE' => $expired->toString()),
595  'limit' => 1
596  ));
597 
598  if ($dbRes->fetch())
599  {
600  $interval = 60;
601  }
602  else
603  {
604  $interval = 24 * 60 * 60;
605  }
606 
607  $agentsList = \CAgent::GetList(array("ID"=>"DESC"), array(
608  "MODULE_ID" => "sale",
609  "NAME" => $calledClass."::deleteOldAgent(%"
610  ));
611  if ($agent = $agentsList->Fetch())
612  {
613  \CAgent::Update($agent['ID'], array("AGENT_INTERVAL" => $interval));
614  }
615  }
616 
617  return $calledClass."::deleteOldAgent(\"$days\", \"$hitLimit\");";
618  }
619 
620  /**
621  * @return array
622  */
623  public static function getManagerLogItems()
624  {
625  return array(
626  "ORDER_SYNCHRONIZATION_IMPORT",
627  "ORDER_SYNCHRONIZATION_EXPORT",
628  "ORDER_SYNCHRONIZATION_EXPORT_ERROR",
629  "ORDER_ADDED",
630  "ORDER_DEDUCTED",
631  "ORDER_MARKED",
632  "ORDER_RESERVED",
633  "ORDER_CANCELED",
634  "ORDER_COMMENTED",
635  "ORDER_STATUS_CHANGED",
636  "ORDER_DELIVERY_ALLOWED",
637  "ORDER_DELIVERY_DOC_CHANGED",
638  "ORDER_PAYMENT_SYSTEM_CHANGED",
639  "ORDER_PAYMENT_VOUCHER_CHANGED",
640  "ORDER_DELIVERY_SYSTEM_CHANGED",
641  "ORDER_PERSON_TYPE_CHANGED",
642  "ORDER_PAYED",
643  "ORDER_TRACKING_NUMBER_CHANGED",
644  "ORDER_USER_DESCRIPTION_CHANGED",
645  "ORDER_PRICE_DELIVERY_CHANGED",
646  "ORDER_PRICE_CHANGED",
647  "ORDER_RESPONSIBLE_CHANGE",
648 
649  "BASKET_ADDED",
650  "BASKET_REMOVED",
651  "BASKET_QUANTITY_CHANGED",
652  "BASKET_PRICE_CHANGED",
653  "PAYMENT_ADDED",
654  "PAYMENT_REMOVED",
655  "PAYMENT_PAID",
656  "PAYMENT_SYSTEM_CHANGED",
657  "PAYMENT_VOUCHER_CHANGED",
658  "PAYMENT_PRICE_CHANGED",
659 
660  "SHIPMENT_ADDED",
661  "SHIPMENT_REMOVED",
662  "SHIPMENT_ITEM_BASKET_ADDED",
663  "SHIPMENT_ITEM_BASKET_REMOVED",
664  "SHIPMENT_DELIVERY_ALLOWED",
665  "SHIPMENT_SHIPPED",
666  "SHIPMENT_MARKED",
667  "SHIPMENT_RESERVED",
668  "SHIPMENT_CANCELED",
669  "SHIPMENT_STATUS_CHANGED",
670  "SHIPMENT_DELIVERY_DOC_CHANGED",
671  "SHIPMENT_TRACKING_NUMBER_CHANGED",
672  "SHIPMENT_PRICE_DELIVERY_CHANGED",
673  "SHIPMENT_AMOUNT_CHANGED",
674  "SHIPMENT_QUANTITY_CHANGED",
675  "SHIPMENT_RESPONSIBLE_CHANGE",
676 
677  "ORDER_UPDATE_ERROR",
678  "BASKET_ITEM_ADD_ERROR",
679  "BASKET_ITEM_UPDATE_ERROR",
680  "SHIPMENT_ADD_ERROR",
681  "SHIPMENT_UPDATE_ERROR",
682  "SHIPMENT_ITEM_ADD_ERROR",
683  "SHIPMENT_ITEM_UPDATE_ERROR",
684  "SHIPMENT_ITEM_STORE_ADD_ERROR",
685  "SHIPMENT_ITEM_STORE_UPDATE_ERROR",
686  "SHIPMENT_ITEM_BASKET_ITEM_EMPTY_ERROR",
687 
688  );
689  }
690 
691 }
static get($moduleId, $name, $default="", $siteId=false)
Returns a value of an option.
static getPoolByEntity($entity, $orderId)
const SALE_ORDER_HISTORY_RECORD_TYPE_ACTION
const SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_1
static getOperationType($entityName, $type)
static checkActionLogLevel($level)
const SALE_ORDER_HISTORY_RECORD_TYPE_FIELD
static addAction($entityName, $orderId, $type, $id=null, $entity=null, array $fields=array(), $level=null)
static getList(array $parameters=array())
static addRecord($entityName, $orderId, $type, $id=null, $entity=null, array $data=array())
static prepareDataForAdd($entityName, $type, $entity=null, array $data=array())
static addLog($entityName, $orderId, $type, $id=null, $entity=null, array $fields=array(), $level=null)
static checkLogLevel($level)
static deleteOldAgent($days, $hitLimit=null)
Delete old records on an agent.
const SALE_ORDER_HISTORY_RECORD_TYPE_DEBUG
static deleteOldInternal($days, $limit=null)
static deleteInternal($primary)
const SALE_ORDER_HISTORY_ACTION_LOG_LEVEL_0
static addField($entityName, $orderId, $field, $oldValue=null, $value=null, $id=null, $entity=null, array $fields=array())
static collectEntityFields($entityName, $orderId, $id=null)
static addInternal($fields)