Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
check.php
1<?php
2
3namespace Bitrix\Sale\Cashbox;
4
17
22abstract class Check extends AbstractCheck
23{
24 public const PAYMENT_OBJECT_COMMODITY = 'commodity';
25 public const PAYMENT_OBJECT_EXCISE = 'excise';
26 public const PAYMENT_OBJECT_JOB = 'job';
27 public const PAYMENT_OBJECT_SERVICE = 'service';
28 public const PAYMENT_OBJECT_PAYMENT = 'payment';
29 public const PAYMENT_OBJECT_GAMBLING_BET = 'gambling_bet';
30 public const PAYMENT_OBJECT_GAMBLING_PRIZE = 'gambling_prize';
31 public const PAYMENT_OBJECT_LOTTERY = 'lottery';
32 public const PAYMENT_OBJECT_LOTTERY_PRIZE = 'lottery_prize';
33 public const PAYMENT_OBJECT_INTELLECTUAL_ACTIVITY = 'intellectual_activity';
34 public const PAYMENT_OBJECT_AGENT_COMMISSION = 'agent_commission';
35 public const PAYMENT_OBJECT_COMPOSITE = 'composite';
36 public const PAYMENT_OBJECT_ANOTHER = 'another';
37 public const PAYMENT_OBJECT_PROPERTY_RIGHT = 'property_right';
38 public const PAYMENT_OBJECT_NON_OPERATING_GAIN = 'non-operating_gain';
39 public const PAYMENT_OBJECT_SALES_TAX = 'sales_tax';
40 public const PAYMENT_OBJECT_RESORT_FEE = 'resort_fee';
41 public const PAYMENT_OBJECT_DEPOSIT = 'deposit';
42 public const PAYMENT_OBJECT_EXPENSE = 'expense';
43 public const PAYMENT_OBJECT_PENSION_INSURANCE_IP = 'pension_insurance_ip';
44 public const PAYMENT_OBJECT_PENSION_INSURANCE = 'pension_insurance';
45 public const PAYMENT_OBJECT_MEDICAL_INSURANCE_IP = 'medical_insurance_ip';
46 public const PAYMENT_OBJECT_MEDICAL_INSURANCE = 'medical_insurance';
47 public const PAYMENT_OBJECT_SOCIAL_INSURANCE = 'social_insurance';
48 public const PAYMENT_OBJECT_CASINO_PAYMENT = 'casino_payment';
49 public const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING_EXCISE = 'commodity_marking_no_marking_excise';
50 public const PAYMENT_OBJECT_COMMODITY_MARKING_EXCISE = 'commodity_marking_excise';
51 public const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING = 'commodity_marking_no_marking';
52 public const PAYMENT_OBJECT_COMMODITY_MARKING = 'commodity_marking';
53 public const PAYMENT_OBJECT_INSURANCE_PREMIUM = 'insurance_premium';
54 public const PAYMENT_OBJECT_FINE = 'fine';
55 public const PAYMENT_OBJECT_TAX = 'tax';
56 public const PAYMENT_OBJECT_AGENT_WITHDRAWALS = 'agent_withdrawals';
57
58 private const MARKING_TYPE_CODE = '444D';
59
61 private $relatedEntities = array();
62
68 public function setRelatedEntities(array $entities)
69 {
70 $this->checkRelatedEntities($entities);
71
72 $this->relatedEntities = $entities;
73
74 foreach ($this->relatedEntities as $type => $entityList)
75 {
76 foreach ($entityList as $entity)
77 {
78 if ($entity instanceof Payment)
79 {
80 $this->fields['SUM'] += $entity->getSum();
81 $this->fields['CURRENCY'] = $entity->getField('CURRENCY');
82 }
83 }
84 }
85 }
86
91 protected function checkRelatedEntities($entities)
92 {
93 foreach ($entities as $type => $entityList)
94 {
95 foreach ($entityList as $entity)
96 {
97 if (static::getSupportedRelatedEntityType() === self::SUPPORTED_ENTITY_TYPE_NONE)
98 {
99 throw new Main\NotSupportedException(static::getType().' is not supported any related entities');
100 }
101
102 if (static::getSupportedRelatedEntityType() === self::SUPPORTED_ENTITY_TYPE_PAYMENT
103 && !($entity instanceof Payment)
104 )
105 {
106 throw new Main\NotSupportedException(static::getType().' is not supported payment as related entity');
107 }
108
109 if (static::getSupportedRelatedEntityType() === self::SUPPORTED_ENTITY_TYPE_SHIPMENT
110 && !($entity instanceof Shipment)
111 )
112 {
113 throw new Main\NotSupportedException(static::getType().' is not supported shipment as related entity');
114 }
115 }
116 }
117 }
118
126 public function getRelatedEntities()
127 {
128 if ($this->relatedEntities)
129 {
130 return $this->relatedEntities;
131 }
132
133 $registry = Registry::getInstance($this->fields['ENTITY_REGISTRY_TYPE']);
134 $order = null;
135
136 $dbRes = CheckRelatedEntitiesTable::getList(array('filter' => array('CHECK_ID' => $this->getField('ID'))));
137 while ($entity = $dbRes->fetch())
138 {
139 if ($order === null)
140 {
141 if ($entity['ENTITY_TYPE'] === CheckRelatedEntitiesTable::ENTITY_TYPE_PAYMENT)
142 {
144 $paymentClassName = $registry->getPaymentClassName();
145 $dbResPayment = $paymentClassName::getList(array(
146 'select' => array('ORDER_ID'),
147 'filter' => array('ID' => $entity['ENTITY_ID'])
148 ));
149 if ($data = $dbResPayment->fetch())
150 {
152 $orderClass = $registry->getOrderClassName();
153 $order = $orderClass::load($data['ORDER_ID']);
154 }
155 }
156 elseif ($entity['ENTITY_TYPE'] === CheckRelatedEntitiesTable::ENTITY_TYPE_SHIPMENT)
157 {
159 $shipmentClassName = $registry->getShipmentClassName();
160 $dbResShipment = $shipmentClassName::getList(array(
161 'select' => array('ORDER_ID'),
162 'filter' => array('ID' => $entity['ENTITY_ID'])
163 ));
164 if ($data = $dbResShipment->fetch())
165 {
167 $orderClass = $registry->getOrderClassName();
168 $order = $orderClass::load($data['ORDER_ID']);
169 }
170 }
171
172 if ($order === null)
173 {
174 continue;
175 }
176 }
177
178 if ($entity['ENTITY_TYPE'] === CheckRelatedEntitiesTable::ENTITY_TYPE_PAYMENT)
179 {
180 $paymentCollection = $order->getPaymentCollection();
181 $this->relatedEntities[$entity['ENTITY_CHECK_TYPE']][] = $paymentCollection->getItemById($entity['ENTITY_ID']);
182 }
183 elseif ($entity['ENTITY_TYPE'] === CheckRelatedEntitiesTable::ENTITY_TYPE_SHIPMENT)
184 {
185 $shipmentCollection = $order->getShipmentCollection();
186 $this->relatedEntities[$entity['ENTITY_CHECK_TYPE']][] = $shipmentCollection->getItemById($entity['ENTITY_ID']);
187 }
188 }
189
190 return $this->relatedEntities;
191 }
192
197 public function save()
198 {
199 $isNew = (int)$this->getField('ID') === 0;
200
201 $result = parent::save();
202 if (!$result->isSuccess())
203 {
204 return $result;
205 }
206
207 if ($isNew)
208 {
209 foreach ($this->relatedEntities as $checkType => $entities)
210 {
211 foreach ($entities as $entity)
212 {
213 if ($entity instanceof Payment)
214 {
216 }
217 else
218 {
220 }
221
223 'CHECK_ID' => $this->fields['ID'],
224 'ENTITY_ID' => $entity->getId(),
225 'ENTITY_TYPE' => $entityType,
226 'ENTITY_CHECK_TYPE' => $checkType,
227 ]);
228 }
229 }
230 }
231
232 return $result;
233 }
234
238 public function getDataForCheck()
239 {
240 $result = [
241 'type' => static::getType(),
242 'calculated_sign' => static::getCalculatedSign(),
243 'unique_id' => $this->getField('ID'),
244 'items' => [],
245 'date_create' => new Main\Type\DateTime()
246 ];
247
248 $data = $this->extractData();
249
250 if ($data)
251 {
252 if (isset($data['ORDER']))
253 {
254 $result['order'] = $data['ORDER'];
255 }
256
257 foreach ($data['PAYMENTS'] as $payment)
258 {
259 $item = [
260 'entity' => $payment['ENTITY'],
261 'type' => $payment['TYPE'],
262 'is_cash' => $payment['IS_CASH'],
263 'sum' => $payment['SUM'],
264 'currency' => $payment['CURRENCY'],
265 ];
266
267 if (isset($payment['ADDITIONAL_PARAMS']))
268 {
269 $item['additional_params'] = $payment['ADDITIONAL_PARAMS'];
270 }
271
272 $result['payments'][] = $item;
273 }
274
275 if (isset($data['PRODUCTS']))
276 {
277 foreach ($data['PRODUCTS'] as $product)
278 {
279 $item = [
280 'entity' => $product['ENTITY'] ?? null,
281 'name' => $product['NAME'],
282 'base_price' => $product['BASE_PRICE'],
283 'price' => $product['PRICE'],
284 'sum' => $product['SUM'],
285 'currency' => $product['CURRENCY'],
286 'quantity' => $product['QUANTITY'],
287 'measure_code' => $product['MEASURE_CODE'] ?? '',
288 'vat' => $product['VAT'] ?? 0,
289 'vat_sum' => $product['VAT_SUM'] ?? 0,
290 'payment_object' => $product['PAYMENT_OBJECT'],
291 'properties' => $product['PROPERTIES'] ?? [],
292 ];
293
294 if (isset($product['NOMENCLATURE_CODE']))
295 {
296 $item['nomenclature_code'] = $product['NOMENCLATURE_CODE'];
297 }
298
299 if (isset($product['MARKING_CODE']))
300 {
301 $item['marking_code'] = $product['MARKING_CODE'];
302 }
303
304 if (isset($product['BARCODE']))
305 {
306 $item['barcode'] = $product['BARCODE'];
307 }
308
309 if (!empty($product['DISCOUNT']))
310 {
311 $item['discount'] = [
312 'discount' => $product['DISCOUNT']['PRICE'],
313 'discount_type' => $product['DISCOUNT']['TYPE'],
314 ];
315 }
316
317 if (isset($product['SUPPLIER_INFO']))
318 {
319 $item['supplier_info'] = [
320 'phones' => $product['SUPPLIER_INFO']['PHONES'] ?? [],
321 'name' => $product['SUPPLIER_INFO']['NAME'] ?? '',
322 'inn' => $product['SUPPLIER_INFO']['INN'] ?? '',
323 ];
324 }
325
326 if (isset($product['ADDITIONAL_PARAMS']))
327 {
328 $item['additional_params'] = $product['ADDITIONAL_PARAMS'];
329 }
330
331 $result['items'][] = $item;
332 }
333 }
334
335 if (isset($data['DELIVERY']))
336 {
337 foreach ($data['DELIVERY'] as $delivery)
338 {
339 $item = [
340 'entity' => $delivery['ENTITY'],
341 'name' => $delivery['NAME'],
342 'base_price' => $delivery['BASE_PRICE'],
343 'price' => $delivery['PRICE'],
344 'sum' => $delivery['SUM'],
345 'currency' => $delivery['CURRENCY'],
346 'quantity' => $delivery['QUANTITY'],
347 'vat' => $delivery['VAT'],
348 'vat_sum' => $delivery['VAT_SUM'],
349 'payment_object' => $delivery['PAYMENT_OBJECT'],
350 ];
351
352 if ($delivery['DISCOUNT'])
353 {
354 $item['discount'] = [
355 'discount' => $delivery['DISCOUNT']['PRICE'],
356 'discount_type' => $delivery['DISCOUNT']['TYPE'],
357 ];
358 }
359
360 if (isset($delivery['ADDITIONAL_PARAMS']))
361 {
362 $item['additional_params'] = $delivery['ADDITIONAL_PARAMS'];
363 }
364
365 $result['items'][] = $item;
366 }
367 }
368
369 if (isset($data['BUYER']))
370 {
371 if (isset($data['BUYER']['EMAIL']))
372 $result['client_email'] = $data['BUYER']['EMAIL'];
373
374 if (isset($data['BUYER']['PHONE']))
375 $result['client_phone'] = $data['BUYER']['PHONE'];
376 }
377
378 if (isset($data['ADDITIONAL_PARAMS']))
379 {
380 $result['additional_params'] = $data['ADDITIONAL_PARAMS'];
381 }
382
383 $result['total_sum'] = $data['TOTAL_SUM'];
384 }
385
386 return $result;
387 }
388
400 private function extractDataFromEntitiesInternal(array $entities)
401 {
402 $result = array();
403
404 $order = null;
405 $discounts = null;
406 $shopPrices = null;
407 $totalSum = 0;
408 $currency = null;
409
410 foreach ($entities as $entity)
411 {
412 if ($order === null)
413 {
414 $order = CheckManager::getOrder($entity);
415 $result['ORDER'] = $order;
416 }
417
418 if ($entity instanceof Payment)
419 {
420 $service = $entity->getPaySystem();
421 $type = $service->getField('IS_CASH') === 'Y' ? static::PAYMENT_TYPE_CASH : static::PAYMENT_TYPE_CASHLESS;
422
423 $result['PAYMENTS'][] = [
424 'ENTITY' => $entity,
425 'IS_CASH' => $service->getField('IS_CASH'),
426 'TYPE' => $type,
427 'SUM' => $entity->getSum(),
428 'CURRENCY' => $entity->getField('CURRENCY'),
429 ];
430
431 $currency = $entity->getField('CURRENCY');
432 $totalSum += $entity->getSum();
433
434 if ($this->isShipmentExists())
435 {
436 continue;
437 }
438
440 foreach ($entity->getPayableItemCollection()->getBasketItems() as $payableItem)
441 {
443 $basketItem = $payableItem->getEntityObject();
444
445 $item = $this->extractDataFromBasketItem($basketItem);
446
447 $item['SUM'] = PriceMaths::roundPrecision($basketItem->getPriceWithVat() * $payableItem->getQuantity());
448 $item['QUANTITY'] = (float)$payableItem->getQuantity();
449
450 $result['PRODUCTS'][] = $item;
451 }
452
453 foreach ($entity->getPayableItemCollection()->getShipments() as $payableItem)
454 {
455 $item = $this->extractDataFromShipment($payableItem->getEntityObject());
456 if ($item)
457 {
458 $item['QUANTITY'] = (float)$payableItem->getQuantity();
459
460 $result['DELIVERY'][] = $item;
461 }
462 }
463 }
464 elseif ($entity instanceof Shipment)
465 {
466 $shipmentItemCollection = $entity->getShipmentItemCollection();
467 $sellableItems = $shipmentItemCollection->getSellableItems();
468
470 foreach ($sellableItems as $shipmentItem)
471 {
472 $basketItem = $shipmentItem->getBasketItem();
473
474 $item = $this->extractDataFromBasketItem($basketItem);
475
476 if ($this->needPrintMarkingCode($basketItem))
477 {
478 $item['QUANTITY'] = 1;
479 $item['SUM'] = $basketItem->getPriceWithVat();
480
481 $shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection();
482 if ($shipmentItemStoreCollection)
483 {
484 foreach ($shipmentItemStoreCollection as $itemStore)
485 {
486 $item['NOMENCLATURE_CODE'] = $this->buildTag1162(
487 $itemStore->getMarkingCode(),
488 $basketItem->getMarkingCodeGroup()
489 );
490 $item['BARCODE'] = $itemStore->getBarcode();
491 $item['MARKING_CODE'] = $itemStore->getMarkingCode();
492
493 $result['PRODUCTS'][] = $item;
494 }
495
496 $diff = $shipmentItem->getQuantity() - $shipmentItemStoreCollection->count();
497 if ($diff)
498 {
499 for ($i = 0; $i < $diff; $i++)
500 {
501 $item['NOMENCLATURE_CODE'] = '';
502 $item['MARKING_CODE'] = '';
503
504 $result['PRODUCTS'][] = $item;
505 }
506 }
507 }
508 }
509 else
510 {
511 $item['SUM'] = PriceMaths::roundPrecision($basketItem->getPriceWithVat() * $shipmentItem->getQuantity());
512 $item['QUANTITY'] = (float)$shipmentItem->getQuantity();
513
514 $shipmentItemStoreCollection = $shipmentItem->getShipmentItemStoreCollection();
515 if (isset($shipmentItemStoreCollection[0]))
516 {
517 $item['BARCODE'] = $shipmentItemStoreCollection[0]->getField('BARCODE');
518 }
519
520 $result['PRODUCTS'][] = $item;
521 }
522 }
523
524 $item = $this->extractDataFromShipment($entity);
525 if ($item)
526 {
527 $result['DELIVERY'][] = $item;
528 }
529 }
530 }
531
532 if ($order !== null)
533 {
534 $result['BUYER'] = array();
535
536 $properties = $order->getPropertyCollection();
537 $email = $properties->getUserEmail();
538 if ($email && $email->getValue())
539 {
540 $result['BUYER']['EMAIL'] = $email->getValue();
541 }
542
543 $phone = $properties->getPhone();
544 if ($phone && $phone->getValue())
545 {
546 $result['BUYER']['PHONE'] = $phone->getValue();
547 }
548
549 if (!$result['BUYER'])
550 {
551 $result['BUYER']['EMAIL'] = Main\Config\Option::get("main", "email_from", "admin@".$_SERVER['SERVER_NAME']);
552 }
553 }
554
555 $result['TOTAL_SUM'] = $totalSum;
556 $result['CURRENCY'] = $currency;
557
558 unset($shopPrices, $discounts);
559
560 return $result;
561 }
562
563 protected function needPrintMarkingCode($basketItem) : bool
564 {
565 return $basketItem->isSupportedMarkingCode();
566 }
567
568 private function isShipmentExists(): bool
569 {
570 foreach ($this->getEntities() as $entity)
571 {
572 if ($entity instanceof Shipment)
573 {
574 return true;
575 }
576 }
577
578 foreach ($this->getRelatedEntities() as $relatedEntities)
579 {
580 foreach ($relatedEntities as $entity)
581 {
582 if ($entity instanceof Shipment)
583 {
584 return true;
585 }
586 }
587 }
588
589 return false;
590 }
591
592 private function extractDataFromShipment(Shipment $shipment) : array
593 {
594 $priceDelivery = (float)$shipment->getPrice();
595 if ($priceDelivery > 0)
596 {
597 $data = [
598 'ENTITY' => $shipment,
599 'NAME' => Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_DELIVERY'),
600 'BASE_PRICE' => (float)$shipment->getField('BASE_PRICE_DELIVERY'),
601 'PRICE' => (float)$shipment->getPrice(),
602 'SUM' => (float)$shipment->getPrice(),
603 'CURRENCY' => $shipment->getCurrency(),
604 'QUANTITY' => 1,
605 'VAT' => $this->getDeliveryVatId($shipment),
606 'PAYMENT_OBJECT' => static::PAYMENT_OBJECT_SERVICE
607 ];
608
609 if ($shipment->isCustomPrice())
610 {
611 $data['BASE_PRICE'] = $shipment->getPrice();
612 }
613 else
614 {
615 if ((float)$shipment->getField('DISCOUNT_PRICE') != 0)
616 {
617 $data['DISCOUNT'] = array(
618 'PRICE' => $shipment->getField('DISCOUNT_PRICE'),
619 'TYPE' => 'C',
620 );
621 }
622 }
623
624 return $data;
625 }
626
627 return [];
628 }
629
630 private function extractDataFromBasketItem(BasketItem $basketItem) : array
631 {
632 static $shopPrices = [];
633
634 $order = $basketItem->getBasket()->getOrder();
635
636 if ($order)
637 {
638 $discounts = $order->getDiscount();
639 if (!$shopPrices)
640 {
641 $shopPrices = $discounts->getShowPrices();
642 }
643 }
644
645 $basketCode = $basketItem->getBasketCode();
646 if (!empty($shopPrices['BASKET'][$basketCode]))
647 {
648 $basketItem->setFieldNoDemand('BASE_PRICE', $shopPrices['BASKET'][$basketCode]['SHOW_BASE_PRICE']);
649 $basketItem->setFieldNoDemand('PRICE', $shopPrices['BASKET'][$basketCode]['SHOW_PRICE']);
650 $basketItem->setFieldNoDemand('DISCOUNT_PRICE', $shopPrices['BASKET'][$basketCode]['SHOW_DISCOUNT']);
651 }
652 unset($basketCode);
653
654 $data = [
655 'ENTITY' => $basketItem,
656 'PRODUCT_ID' => $basketItem->getProductId(),
657 'NAME' => $basketItem->getField('NAME'),
658 'BASE_PRICE' => $basketItem->getBasePriceWithVat(),
659 'PRICE' => $basketItem->getPriceWithVat(),
660 'SUM' => $basketItem->getFinalPrice(),
661 'CURRENCY' => $basketItem->getCurrency(),
662 'QUANTITY' => (float)$basketItem->getQuantity(),
663 'MEASURE_CODE' => $basketItem->getField('MEASURE_CODE'),
664 'VAT' => $this->getProductVatId($basketItem),
665 'PAYMENT_OBJECT' => $this->getPaymentObject($basketItem),
666 ];
667
668 if ($order)
669 {
670 $siteId = $order->getSiteId();
671 $propertiesCodes = ['ARTNUMBER'];
672 $itemProperties = self::getCatalogPropertiesForItem($basketItem->getProductId(), $propertiesCodes, $siteId);
673 $data['PROPERTIES'] = $itemProperties;
674 }
675 else
676 {
677 $data['PROPERTIES'] = [];
678 }
679
680 if ($basketItem->isCustomPrice())
681 {
682 $data['BASE_PRICE'] = $basketItem->getPriceWithVat();
683 }
684 else
685 {
686 if ((float)$basketItem->getDiscountPrice() != 0)
687 {
688 $data['DISCOUNT'] = [
689 'PRICE' => (float)$basketItem->getDiscountPrice(),
690 'TYPE' => 'C',
691 ];
692 }
693 }
694
695 return $data;
696 }
697
706 private static function getCatalogPropertiesForItem($itemId, $itemPropertiesCodes, $siteId): array
707 {
708 $propertiesFieldNames = [];
709 foreach ($itemPropertiesCodes as $propertyCode)
710 {
711 $propertiesFieldNames[] = 'PROPERTY_' . $propertyCode;
712 }
713
714 $result = [];
715 $catalogData = Admin\Product::getData([$itemId], $siteId, $propertiesFieldNames);
716 foreach ($catalogData as $item)
717 {
718 foreach ($itemPropertiesCodes as $propertyCode)
719 {
720 if (
721 isset($item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'])
722 && $item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'] !== '&nbsp'
723 )
724 {
725 $result[$propertyCode] = $item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'];
726 }
727 }
728 }
729
730 return $result;
731 }
732
738 protected function buildTag1162(string $markingCode, string $markingCodeGroup) : string
739 {
740 [$gtin, $serial] = $this->parseMarkingCode($markingCode, $markingCodeGroup);
741
742 $hex =
743 self::MARKING_TYPE_CODE.
744 $this->convertToBinaryFormat($gtin, 6).
745 $this->convertCharsToHex($serial)
746 ;
747
748 return hex2bin($hex);
749 }
750
756 private function parseMarkingCode(string $code, string $group) : array
757 {
758 $gtin = mb_substr($code, 2, 14);
759 $serial = mb_substr($code, 18, $this->getSnLength($group));
760
761 return [$gtin, $serial];
762 }
763
768 private function getSnLength(string $group) : int
769 {
770 if ((string)$group === '9840')
771 {
772 return 20;
773 }
774
775 return 13;
776 }
777
783 protected function convertToBinaryFormat($string, $size) : string
784 {
785 $result = '';
786
787 for ($i = 0; $i < $size; $i++)
788 {
789 $hex = dechex(($string >> (8 * $i)) & 0xFF);
790 if (mb_strlen($hex) === 1)
791 {
792 $hex = '0'.$hex;
793 }
794
795 $result = ToUpper($hex).$result;
796 }
797
798 return $result;
799 }
800
805 protected function convertCharsToHex($string) : string
806 {
807 $result = '';
808
809 for ($i = 0, $len = mb_strlen($string); $i < $len; $i++)
810 {
811 $hex = dechex(ord($string[$i]));
812 if (mb_strlen($hex) === 1)
813 {
814 $hex = '0'.$hex;
815 }
816
817 $result .= ToUpper($hex);
818 }
819
820 return $result;
821 }
822
833 protected function extractDataInternal()
834 {
835 $entities = $this->getEntities();
836 $result = $this->extractDataFromEntitiesInternal($entities);
837
838 $relatedEntities = $this->getRelatedEntities();
839 if ($relatedEntities)
840 {
841 foreach ($this->relatedEntities as $type => $relatedEntities)
842 {
843 $data = $this->extractDataFromEntitiesInternal($relatedEntities);
844
845 if (isset($data['PAYMENTS']))
846 {
847 foreach ($data['PAYMENTS'] as $item)
848 {
849 $item['TYPE'] = $type;
850 $result['PAYMENTS'][] = $item;
851 }
852 }
853
854 if (isset($data['PRODUCTS']))
855 {
856 foreach ($data['PRODUCTS'] as $item)
857 $result['PRODUCTS'][] = $item;
858 }
859
860 if (isset($data['DELIVERY']))
861 {
862 foreach ($data['DELIVERY'] as $item)
863 $result['DELIVERY'][] = $item;
864 }
865
866 $result['TOTAL_SUM'] += $data['TOTAL_SUM'];
867 }
868 }
869
870 return $result;
871 }
872
880 protected function getDeliveryVatId(Shipment $shipment)
881 {
882 $calcDeliveryTax = Main\Config\Option::get("sale", "COUNT_DELIVERY_TAX", "N");
883 if ($calcDeliveryTax === 'Y' && $service = $shipment->getDelivery())
884 {
885 return $service->getVatId();
886 }
887
888 return 0;
889 }
890
899 protected function getProductVatId(BasketItem $basketItem)
900 {
901 static $vatList = array();
902
903 if (!isset($vatList[$basketItem->getProductId()]))
904 {
905 $vatId = $this->getVatIdByProductId($basketItem->getProductId());
906 if ($vatId === 0)
907 {
908 $vatRate = (int)((float)$basketItem->getVatRate() * 100);
909 if ($vatRate > 0)
910 {
911 $vatId = $this->getVatIdByVatRate($vatRate);
912 }
913 }
914
915 $vatList[$basketItem->getProductId()] = (int)$vatId;
916 }
917
918 return $vatList[$basketItem->getProductId()];
919 }
920
926 private function getVatIdByProductId($productId)
927 {
928 $vatId = 0;
929 if (Main\Loader::includeModule('catalog'))
930 {
931 $dbRes = \CCatalogProduct::GetVATInfo($productId);
932 $vat = $dbRes->Fetch();
933 if ($vat)
934 {
935 $vatId = (int)$vat['ID'];
936 }
937 }
938
939 return $vatId;
940 }
941
945 public function validate()
946 {
947 $result = new Result();
948
949 $data = $this->extractData();
950
951 if (!isset($data['PRODUCTS']))
952 {
953 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_NO_PRODUCTS')));
954 }
955 else
956 {
957 $errors = [];
958
959 foreach ($data['PRODUCTS'] as $product)
960 {
961 if (isset($product['MARKING_CODE']) && $product['MARKING_CODE'] === '')
962 {
963 if (isset($errors[$product['PRODUCT_ID']]))
964 {
965 continue;
966 }
967
968 $errors[$product['PRODUCT_ID']] = new Main\Error(
969 Main\Localization\Loc::getMessage(
970 'SALE_CASHBOX_CHECK_ERROR_NO_NOMENCLATURE_CODE',
971 [
972 '#PRODUCT_NAME#' => $product['NAME']
973 ]
974 )
975 );
976 }
977 }
978
979 if ($errors)
980 {
981 $result->addErrors($errors);
982 }
983 }
984
985 if (!$this->isCorrectSum($data))
986 {
987 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_CHECK_SUM')));
988 }
989
990 if (!isset($data['BUYER']) || !$data['BUYER'])
991 {
992 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_NO_BUYER_INFO')));
993 }
994
995 return $result;
996 }
997
1002 private function isCorrectSum($data)
1003 {
1004 $eps = 0.00001;
1005
1006 $productSum = 0;
1007 if (!empty($data['PRODUCTS']))
1008 {
1009 foreach ($data['PRODUCTS'] as $item)
1010 $productSum += $item['SUM'];
1011 }
1012
1013 if (!empty($data['DELIVERY']))
1014 {
1015 foreach ($data['DELIVERY'] as $delivery)
1016 {
1017 $productSum += $delivery['PRICE'];
1018 }
1019 }
1020
1021 $paymentSum = 0;
1022 if (!empty($data['PAYMENTS']))
1023 {
1024 foreach ($data['PAYMENTS'] as $payment)
1025 {
1026 $paymentSum += $payment['SUM'];
1027 }
1028 }
1029
1030 return abs($productSum - $paymentSum) < $eps;
1031 }
1032
1036 public static function getSupportedEntityType()
1037 {
1038 return static::SUPPORTED_ENTITY_TYPE_PAYMENT;
1039 }
1040
1044 public static function getSupportedRelatedEntityType()
1045 {
1046 return static::SUPPORTED_ENTITY_TYPE_PAYMENT;
1047 }
1048
1062 protected function extractDataFromEntities(array $entities)
1063 {
1064 $result = $this->extractDataFromEntitiesInternal($entities);
1065
1066 $event = new Main\Event('sale', static::EVENT_ON_CHECK_PREPARE_DATA, array($result, static::getType()));
1067 $event->send();
1068
1069 if ($event->getResults())
1070 {
1071 foreach ($event->getResults() as $eventResult)
1072 {
1073 if ($eventResult->getType() !== Main\EventResult::ERROR)
1074 {
1075 $result = $eventResult->getParameters();
1076 }
1077 }
1078 }
1079
1080 return $result;
1081 }
1082
1083 protected function getPaymentObject(BasketItem $basketItem): string
1084 {
1085 if ($basketItem->isService())
1086 {
1087 return static::PAYMENT_OBJECT_SERVICE;
1088 }
1089
1090 return $this->needPrintMarkingCode($basketItem)
1091 ? static::PAYMENT_OBJECT_COMMODITY_MARKING
1092 : static::PAYMENT_OBJECT_COMMODITY
1093 ;
1094 }
1095}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getList(array $parameters=array())
getPaymentObject(BasketItem $basketItem)
Definition check.php:1083
const PAYMENT_OBJECT_SOCIAL_INSURANCE
Definition check.php:47
const PAYMENT_OBJECT_LOTTERY_PRIZE
Definition check.php:32
const PAYMENT_OBJECT_MEDICAL_INSURANCE_IP
Definition check.php:45
const PAYMENT_OBJECT_COMMODITY_MARKING_EXCISE
Definition check.php:50
const PAYMENT_OBJECT_NON_OPERATING_GAIN
Definition check.php:38
convertToBinaryFormat($string, $size)
Definition check.php:783
static getSupportedEntityType()
Definition check.php:1036
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING_EXCISE
Definition check.php:49
getDeliveryVatId(Shipment $shipment)
Definition check.php:880
const PAYMENT_OBJECT_RESORT_FEE
Definition check.php:40
const PAYMENT_OBJECT_PENSION_INSURANCE_IP
Definition check.php:43
static getSupportedRelatedEntityType()
Definition check.php:1044
const PAYMENT_OBJECT_PROPERTY_RIGHT
Definition check.php:37
const PAYMENT_OBJECT_GAMBLING_PRIZE
Definition check.php:30
buildTag1162(string $markingCode, string $markingCodeGroup)
Definition check.php:738
const PAYMENT_OBJECT_COMMODITY_MARKING
Definition check.php:52
needPrintMarkingCode($basketItem)
Definition check.php:563
const PAYMENT_OBJECT_AGENT_COMMISSION
Definition check.php:34
const PAYMENT_OBJECT_MEDICAL_INSURANCE
Definition check.php:46
checkRelatedEntities($entities)
Definition check.php:91
getProductVatId(BasketItem $basketItem)
Definition check.php:899
setRelatedEntities(array $entities)
Definition check.php:68
const PAYMENT_OBJECT_INTELLECTUAL_ACTIVITY
Definition check.php:33
const PAYMENT_OBJECT_INSURANCE_PREMIUM
Definition check.php:53
const PAYMENT_OBJECT_AGENT_WITHDRAWALS
Definition check.php:56
const PAYMENT_OBJECT_GAMBLING_BET
Definition check.php:29
const PAYMENT_OBJECT_CASINO_PAYMENT
Definition check.php:48
const PAYMENT_OBJECT_PENSION_INSURANCE
Definition check.php:44
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING
Definition check.php:51
extractDataFromEntities(array $entities)
Definition check.php:1062
static roundPrecision($value)
static getInstance($type)
Definition registry.php:183