1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
check.php
См. документацию.
1<?php
2
3namespace Bitrix\Sale\Cashbox;
4
5use Bitrix\Main;
6use Bitrix\Sale\BasketItem;
7use Bitrix\Sale\Cashbox\Internals\CheckRelatedEntitiesTable;
8use Bitrix\Sale\Order;
9use Bitrix\Sale\PayableBasketItem;
10use Bitrix\Sale\Payment;
11use Bitrix\Sale\PriceMaths;
12use Bitrix\Sale\Registry;
13use Bitrix\Sale\Result;
14use Bitrix\Sale\Helpers\Admin;
15use Bitrix\Sale\Shipment;
16use Bitrix\Sale\ShipmentItem;
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
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 {
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 }
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
179 {
180 $paymentCollection = $order->getPaymentCollection();
181 $this->relatedEntities[$entity['ENTITY_CHECK_TYPE']][] = $paymentCollection->getItemById($entity['ENTITY_ID']);
182 }
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 'VAT_SUM' => $basketItem->getVat(),
666 'PAYMENT_OBJECT' => $this->getPaymentObject($basketItem),
667 ];
668
669 if ($order)
670 {
671 $siteId = $order->getSiteId();
672 $propertiesCodes = ['ARTNUMBER'];
673 $itemProperties = self::getCatalogPropertiesForItem($basketItem->getProductId(), $propertiesCodes, $siteId);
674 $data['PROPERTIES'] = $itemProperties;
675 }
676 else
677 {
678 $data['PROPERTIES'] = [];
679 }
680
681 if ($basketItem->isCustomPrice())
682 {
683 $data['BASE_PRICE'] = $basketItem->getPriceWithVat();
684 }
685 else
686 {
687 if ((float)$basketItem->getDiscountPrice() != 0)
688 {
689 $data['DISCOUNT'] = [
690 'PRICE' => (float)$basketItem->getDiscountPrice(),
691 'TYPE' => 'C',
692 ];
693 }
694 }
695
696 return $data;
697 }
698
707 private static function getCatalogPropertiesForItem($itemId, $itemPropertiesCodes, $siteId): array
708 {
709 $propertiesFieldNames = [];
710 foreach ($itemPropertiesCodes as $propertyCode)
711 {
712 $propertiesFieldNames[] = 'PROPERTY_' . $propertyCode;
713 }
714
715 $result = [];
716 $catalogData = Admin\Product::getData([$itemId], $siteId, $propertiesFieldNames);
717 foreach ($catalogData as $item)
718 {
719 foreach ($itemPropertiesCodes as $propertyCode)
720 {
721 if (
722 isset($item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'])
723 && $item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'] !== '&nbsp'
724 )
725 {
726 $result[$propertyCode] = $item['PRODUCT_PROPS_VALUES']['PROPERTY_' . $propertyCode . '_VALUE'];
727 }
728 }
729 }
730
731 return $result;
732 }
733
739 protected function buildTag1162(string $markingCode, string $markingCodeGroup) : string
740 {
741 [$gtin, $serial] = $this->parseMarkingCode($markingCode, $markingCodeGroup);
742
743 $hex =
744 self::MARKING_TYPE_CODE.
745 $this->convertToBinaryFormat($gtin, 6).
746 $this->convertCharsToHex($serial)
747 ;
748
749 return hex2bin($hex);
750 }
751
757 private function parseMarkingCode(string $code, string $group) : array
758 {
759 $gtin = mb_substr($code, 2, 14);
760 $serial = mb_substr($code, 18, $this->getSnLength($group));
761
762 return [$gtin, $serial];
763 }
764
769 private function getSnLength(string $group) : int
770 {
771 if ((string)$group === '9840')
772 {
773 return 20;
774 }
775
776 return 13;
777 }
778
784 protected function convertToBinaryFormat($string, $size) : string
785 {
786 $result = '';
787
788 for ($i = 0; $i < $size; $i++)
789 {
790 $hex = dechex(($string >> (8 * $i)) & 0xFF);
791 if (mb_strlen($hex) === 1)
792 {
793 $hex = '0'.$hex;
794 }
795
796 $result = mb_strtoupper($hex).$result;
797 }
798
799 return $result;
800 }
801
806 protected function convertCharsToHex($string) : string
807 {
808 $result = '';
809
810 for ($i = 0, $len = mb_strlen($string); $i < $len; $i++)
811 {
812 $hex = dechex(ord($string[$i]));
813 if (mb_strlen($hex) === 1)
814 {
815 $hex = '0'.$hex;
816 }
817
818 $result .= mb_strtoupper($hex);
819 }
820
821 return $result;
822 }
823
834 protected function extractDataInternal()
835 {
836 $entities = $this->getEntities();
837 $result = $this->extractDataFromEntitiesInternal($entities);
838
839 $relatedEntities = $this->getRelatedEntities();
840 if ($relatedEntities)
841 {
842 foreach ($this->relatedEntities as $type => $relatedEntities)
843 {
844 $data = $this->extractDataFromEntitiesInternal($relatedEntities);
845
846 if (isset($data['PAYMENTS']))
847 {
848 foreach ($data['PAYMENTS'] as $item)
849 {
850 $item['TYPE'] = $type;
851 $result['PAYMENTS'][] = $item;
852 }
853 }
854
855 if (isset($data['PRODUCTS']))
856 {
857 foreach ($data['PRODUCTS'] as $item)
858 $result['PRODUCTS'][] = $item;
859 }
860
861 if (isset($data['DELIVERY']))
862 {
863 foreach ($data['DELIVERY'] as $item)
864 $result['DELIVERY'][] = $item;
865 }
866
867 $result['TOTAL_SUM'] += $data['TOTAL_SUM'];
868 }
869 }
870
871 return $result;
872 }
873
881 protected function getDeliveryVatId(Shipment $shipment)
882 {
883 $calcDeliveryTax = Main\Config\Option::get("sale", "COUNT_DELIVERY_TAX", "N");
884 if ($calcDeliveryTax === 'Y' && $service = $shipment->getDelivery())
885 {
886 return $service->getVatId();
887 }
888
889 return 0;
890 }
891
900 protected function getProductVatId(BasketItem $basketItem)
901 {
902 static $vatList = array();
903
904 if (!isset($vatList[$basketItem->getProductId()]))
905 {
906 $vatId = $this->getVatIdByProductId($basketItem->getProductId());
907 if ($vatId === 0)
908 {
909 $vatRate = (int)((float)$basketItem->getVatRate() * 100);
910 if ($vatRate > 0)
911 {
912 $vatId = $this->getVatIdByVatRate($vatRate);
913 }
914 }
915
916 $vatList[$basketItem->getProductId()] = (int)$vatId;
917 }
918
919 return $vatList[$basketItem->getProductId()];
920 }
921
927 private function getVatIdByProductId($productId)
928 {
929 $vatId = 0;
930 if (Main\Loader::includeModule('catalog'))
931 {
933 $vat = $dbRes->Fetch();
934 if ($vat)
935 {
936 $vatId = (int)$vat['ID'];
937 }
938 }
939
940 return $vatId;
941 }
942
946 public function validate()
947 {
948 $result = new Result();
949
950 $data = $this->extractData();
951
952 if (!isset($data['PRODUCTS']))
953 {
954 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_NO_PRODUCTS')));
955 }
956 else
957 {
958 $errors = [];
959
960 foreach ($data['PRODUCTS'] as $product)
961 {
962 if (isset($product['MARKING_CODE']) && $product['MARKING_CODE'] === '')
963 {
964 if (isset($errors[$product['PRODUCT_ID']]))
965 {
966 continue;
967 }
968
969 $errors[$product['PRODUCT_ID']] = new Main\Error(
970 Main\Localization\Loc::getMessage(
971 'SALE_CASHBOX_CHECK_ERROR_NO_NOMENCLATURE_CODE',
972 [
973 '#PRODUCT_NAME#' => $product['NAME']
974 ]
975 )
976 );
977 }
978 }
979
980 if ($errors)
981 {
982 $result->addErrors($errors);
983 }
984 }
985
986 if (!$this->isCorrectSum($data))
987 {
988 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_CHECK_SUM')));
989 }
990
991 if (!isset($data['BUYER']) || !$data['BUYER'])
992 {
993 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('SALE_CASHBOX_CHECK_ERROR_NO_BUYER_INFO')));
994 }
995
996 return $result;
997 }
998
1003 private function isCorrectSum($data)
1004 {
1005 $eps = 0.00001;
1006
1007 $productSum = 0;
1008 if (!empty($data['PRODUCTS']))
1009 {
1010 foreach ($data['PRODUCTS'] as $item)
1011 $productSum += $item['SUM'];
1012 }
1013
1014 if (!empty($data['DELIVERY']))
1015 {
1016 foreach ($data['DELIVERY'] as $delivery)
1017 {
1018 $productSum += $delivery['PRICE'];
1019 }
1020 }
1021
1022 $paymentSum = 0;
1023 if (!empty($data['PAYMENTS']))
1024 {
1025 foreach ($data['PAYMENTS'] as $payment)
1026 {
1027 $paymentSum += $payment['SUM'];
1028 }
1029 }
1030
1031 return abs($productSum - $paymentSum) < $eps;
1032 }
1033
1037 public static function getSupportedEntityType()
1038 {
1039 return static::SUPPORTED_ENTITY_TYPE_PAYMENT;
1040 }
1041
1045 public static function getSupportedRelatedEntityType()
1046 {
1047 return static::SUPPORTED_ENTITY_TYPE_PAYMENT;
1048 }
1049
1064 {
1065 $result = $this->extractDataFromEntitiesInternal($entities);
1066
1067 $event = new Main\Event('sale', static::EVENT_ON_CHECK_PREPARE_DATA, array($result, static::getType()));
1068 $event->send();
1069
1070 if ($event->getResults())
1071 {
1072 foreach ($event->getResults() as $eventResult)
1073 {
1074 if ($eventResult->getType() !== Main\EventResult::ERROR)
1075 {
1076 $result = $eventResult->getParameters();
1077 }
1078 }
1079 }
1080
1081 return $result;
1082 }
1083
1084 protected function getPaymentObject(BasketItem $basketItem): string
1085 {
1086 if ($basketItem->isService())
1087 {
1088 return static::PAYMENT_OBJECT_SERVICE;
1089 }
1090
1091 return $this->needPrintMarkingCode($basketItem)
1092 ? static::PAYMENT_OBJECT_COMMODITY_MARKING
1093 : static::PAYMENT_OBJECT_COMMODITY
1094 ;
1095 }
1096}
$type
Определения options.php:106
$catalogData
Определения options.php:2236
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
Определения error.php:15
Определения event.php:5
static getList(array $parameters=array())
Определения datamanager.php:431
static add(array $data)
Определения datamanager.php:877
isService()
Определения basketitem.php:1201
getVatIdByVatRate($vatRate)
Определения abstractcheck.php:371
const PAYMENT_OBJECT_EXCISE
Определения check.php:25
validate()
Определения check.php:946
const PAYMENT_OBJECT_LOTTERY
Определения check.php:31
extractDataInternal()
Определения check.php:834
getPaymentObject(BasketItem $basketItem)
Определения check.php:1084
const PAYMENT_OBJECT_SOCIAL_INSURANCE
Определения check.php:47
const PAYMENT_OBJECT_COMPOSITE
Определения check.php:35
const PAYMENT_OBJECT_LOTTERY_PRIZE
Определения check.php:32
const PAYMENT_OBJECT_MEDICAL_INSURANCE_IP
Определения check.php:45
const PAYMENT_OBJECT_COMMODITY_MARKING_EXCISE
Определения check.php:50
const PAYMENT_OBJECT_NON_OPERATING_GAIN
Определения check.php:38
convertToBinaryFormat($string, $size)
Определения check.php:784
getDataForCheck()
Определения check.php:238
const PAYMENT_OBJECT_TAX
Определения check.php:55
static getSupportedEntityType()
Определения check.php:1037
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING_EXCISE
Определения check.php:49
getDeliveryVatId(Shipment $shipment)
Определения check.php:881
const PAYMENT_OBJECT_RESORT_FEE
Определения check.php:40
const PAYMENT_OBJECT_PENSION_INSURANCE_IP
Определения check.php:43
const PAYMENT_OBJECT_FINE
Определения check.php:54
static getSupportedRelatedEntityType()
Определения check.php:1045
const PAYMENT_OBJECT_PROPERTY_RIGHT
Определения check.php:37
const PAYMENT_OBJECT_GAMBLING_PRIZE
Определения check.php:30
buildTag1162(string $markingCode, string $markingCodeGroup)
Определения check.php:739
const PAYMENT_OBJECT_COMMODITY_MARKING
Определения check.php:52
const PAYMENT_OBJECT_COMMODITY
Определения check.php:24
needPrintMarkingCode($basketItem)
Определения check.php:563
const PAYMENT_OBJECT_AGENT_COMMISSION
Определения check.php:34
const PAYMENT_OBJECT_ANOTHER
Определения check.php:36
const PAYMENT_OBJECT_DEPOSIT
Определения check.php:41
const PAYMENT_OBJECT_MEDICAL_INSURANCE
Определения check.php:46
checkRelatedEntities($entities)
Определения check.php:91
getProductVatId(BasketItem $basketItem)
Определения check.php:900
const PAYMENT_OBJECT_SERVICE
Определения check.php:27
setRelatedEntities(array $entities)
Определения check.php:68
const PAYMENT_OBJECT_INTELLECTUAL_ACTIVITY
Определения check.php:33
const PAYMENT_OBJECT_INSURANCE_PREMIUM
Определения check.php:53
const PAYMENT_OBJECT_AGENT_WITHDRAWALS
Определения check.php:56
const PAYMENT_OBJECT_PAYMENT
Определения check.php:28
convertCharsToHex($string)
Определения check.php:806
const PAYMENT_OBJECT_EXPENSE
Определения check.php:42
const PAYMENT_OBJECT_GAMBLING_BET
Определения check.php:29
const PAYMENT_OBJECT_CASINO_PAYMENT
Определения check.php:48
const PAYMENT_OBJECT_PENSION_INSURANCE
Определения check.php:44
const PAYMENT_OBJECT_JOB
Определения check.php:26
const PAYMENT_OBJECT_COMMODITY_MARKING_NO_MARKING
Определения check.php:51
extractDataFromEntities(array $entities)
Определения check.php:1063
const PAYMENT_OBJECT_SALES_TAX
Определения check.php:39
save()
Определения check.php:197
Определения payment.php:19
static roundPrecision($value)
Определения pricemaths.php:16
static getInstance($type)
Определения registry.php:183
getDelivery()
Определения shipment.php:1341
static GetVATInfo($PRODUCT_ID)
Определения product.php:185
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$entity
$errors
Определения iblock_catalog_edit.php:74
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$siteId
Определения ajax.php:8
$payment
Определения payment.php:14
$order
Определения payment.php:8
$paymentCollection
Определения payment.php:11
$service
Определения payment.php:18
$email
Определения payment.php:49
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$i
Определения factura.php:643
$currency
Определения template.php:266
$vat
Определения template.php:273
$totalSum
Определения template.php:410
$dbRes
Определения yandex_detail.php:168
$vatList
Определения yandex_run.php:916