1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
importonecsubordinatesale.php
См. документацию.
1<?php
2namespace Bitrix\Sale\Exchange;
3
4
5use Bitrix\Sale\Exchange\Entity\OrderImport;
6use Bitrix\Sale\Exchange\Entity\SubordinateSale\EntityImportFactory;
7use Bitrix\Sale\Exchange\OneC\DocumentBase;
8use Bitrix\Sale\Exchange\OneC\DocumentType;
9use Bitrix\Sale\Exchange\OneC\PaymentCardDocument;
10use Bitrix\Sale\Exchange\OneC\SubordinateSale\ConverterFactory;
11use Bitrix\Sale\Exchange\OneC\SubordinateSale\CriterionShipment;
12use Bitrix\Sale\Exchange\OneC\SubordinateSale\DocumentFactory;
13use Bitrix\Sale\Exchange\OneC\SubordinateSale\ShipmentDocument;
14use Bitrix\Sale\Order;
15use Bitrix\Sale\Payment;
16use Bitrix\Sale\Result;
17use Bitrix\Sale\Shipment;
18
20{
21 public static function configuration()
22 {
24
25 parent::configuration();
26 }
27
32 protected function convert(array $documents)
33 {
34 $documentOrder = $this->getDocumentByTypeId(EntityType::ORDER, $documents);
35
36 if($documentOrder instanceof OneC\OrderDocument)
37 {
38 $fieldsOrder = $documentOrder->getFieldValues();
39 $itemsOrder = $this->getProductsItems($fieldsOrder);
40
41 if(is_array($fieldsOrder['SUBORDINATES']))
42 {
43 foreach ($fieldsOrder['SUBORDINATES'] as $subordinateDocumentFields)
44 {
45 $typeId = $this->resolveSubordinateDocumentTypeId($subordinateDocumentFields);
46
47 if($typeId == static::getShipmentEntityTypeId())
48 {
49 $subordinateDocumentItems = array();
50 $itemsSubordinate = $this->getProductsItems($subordinateDocumentFields);
51
52 foreach ($itemsSubordinate as $itemSubordinate)
53 {
54 $xmlId = key($itemSubordinate);
55
56 if($xmlId == self::DELIVERY_SERVICE_XMLID)
57 {
58 $itemSubordinate[$xmlId]['TYPE'] = ImportBase::ITEM_SERVICE;
59 $subordinateDocumentItems[] = $itemSubordinate;
60 }
61 else
62 {
63 $item = $this->getItemByParam($xmlId, $itemsOrder);
64
65 if($item !== null)
66 {
67 $item[$xmlId]['QUANTITY'] = $itemSubordinate[$xmlId]['QUANTITY'];
68 $subordinateDocumentItems[] = $item;
69 }
70 }
71 }
72
73 unset($subordinateDocumentFields['ITEMS']);
74 unset($subordinateDocumentFields['ITEMS_FIELDS']);
75
76 if(count($subordinateDocumentItems)>0)
77 {
78 $subordinateDocumentFields['ITEMS'] = $subordinateDocumentItems;
79 }
80 }
81
82 $document = OneC\DocumentImportFactory::create($typeId);
83 $document->setFields($subordinateDocumentFields);
84 $documents[] = $document;
85 }
86 $documentOrder->setField('SUBORDINATES', '');
87 }
88
89 //region Presset - генерируем фэйковую отгрузку
90 /*
91 * генерируем фэйковую отгрузку, если выполнены условия
92 * 1 обмен с новым модулем от 1С,
93 * 2 отгрузки не переданы в подчиненных документах
94 * 3 все отгрузки по заказу в БУС в статусе не отгружено
95 * 4 и от 1С в табличной части заказа передана ORDER_DELIVERY
96 * */
97 if(!$this->hasDocumentByTypeId(static::getShipmentEntityTypeId(), $documents))
98 {
99 if($this->deliveryServiceExists($itemsOrder))
100 {
101 //$deliveryItem
102 $entityOrder = $this->convertDocument($documentOrder);
103 if($entityOrder->getFieldValues()['TRAITS']['ID']>0)
104 {
105 self::load($entityOrder, ['ID'=>$entityOrder->getFieldValues()['TRAITS']['ID']]);
107 $order = $entityOrder->getEntity();
108 if(!$order->isShipped())
109 {
110 $shipmentList = [];
111 $shipmentIsShipped = false;
113 foreach ($order->getShipmentCollection() as $shipment)
114 {
115 if($shipment->isShipped())
116 {
117 $shipmentIsShipped = true;
118 break;
119 }
120
121 if(!$shipment->isSystem())
122 {
123 $shipmentList[] = $shipment->getFieldValues();
124 }
125 }
126
127 if(!$shipmentIsShipped)
128 {
129 if(count($shipmentList)>0)
130 {
131 //системная и реальная отгрузка
132 $externalId = current($shipmentList)['ID_1C'];
133 $shipmentFields['ID_1C'] = $externalId == ''? $documentOrder->getField('ID_1C'):$externalId;
134 $shipmentFields['ID'] = current($shipmentList)['ID'];
135 }
136 else
137 {
138 //только системная отгрузка
139 $shipmentFields['ID_1C'] = $documentOrder->getField('ID_1C');
140 }
141 // колличество и вся табличная часть всегда береться из заказа т.к. все отгрузки вводятся в 1С и на сайте вообще не может измениться что-то в отгрузке. (требования 1С)
142 $shipmentFields['ITEMS'] = $itemsOrder;
143
144 $documentShipment = new ShipmentDocument();
145 $documentShipment->setFields($shipmentFields);
146 $documents[] = $documentShipment;
147 }
148 }
149 }
150 }
151 }
152 //endregion
153
154 //region - оплаты
155
156 // от 1С может приходить только оплаченные оплаты, шаблоны приходить не могут.
157 // Удаляем все не оплаченные оплаты из коллекции документов оплат
158
159 $documents = $this->deletePaymentDocumentNotPaid($documents);
160
162 $entityOrder = $this->convertDocument($documentOrder);
163 if($entityOrder->getFieldValues()['TRAITS']['ID']>0)
164 {
165 self::load($entityOrder, ['ID'=>$entityOrder->getFieldValues()['TRAITS']['ID']]);
167 $order = $entityOrder->getEntity();
168
169 if(!empty($order))
170 {
171 $hasPayment = $order->isPaid() || $this->orderPartiallyIsPaid($order);
172
173 if($this->hasPaymentDocuments($documents))
174 {
175 // оплаченных оплат - нет
176 if(!$hasPayment)
177 {
178 if($order->getPrice() <= $this->getPaymentDocumentsPaidSum($documents))
179 {
180 //region 2. Из 1С приходит полная оплата - удаляем шаблоны в БУС, заменяем на оплату из 1С
181 //endregion
182 }
183 }
184
185 // частичная оплата заказа коллекцией документов оплат
186 $paymentDocumentsPaidSum = $this->getPaymentDocumentsPaidSum($documents);
187 if($order->getPrice() > $paymentDocumentsPaidSum)
188 {
189 //region 3. Из 1С приходит частичная оплата - пытаемся сверить по сумме и по типу,
190 // если подходит - удаляем шаблон с такой же суммой и типом, создаем оплату из 1С.
191 // Остальные шаблоны оплаты не трогаем.
192 // Если по выбранным критериям (сумма + тип) выбираются 2 и более шаблонов выбираем последнюю оплату по ID
193
194 //$r = $this->documentPaymentReplaceId($order, $documents);
195 //TODO: оплата должна удаляться через срзданный документ удаления оплаты.
196 $r = $this->deletePaymentToReplace($order, $documents);
197 if($r->isSuccess())
198 {
199 $entityOrder->save();
200 }
201
202 if($r->getData()['IS_REPLACE'] === true)
203 {
204 static::setConfig(static::DELETE_IF_NOT_FOUND_RELATED_PAYMENT_DOCUMENT, false);
205 }
206 else
207 {
208 //3.1. Если по сумме ничего не находим.
209 //- удаляем все шаблоны
210 //- если есть оплаченная оплата в БУС, которая не пришла из 1С – коллизия
211 //-обновляем те оплаты информация по которым пришла от 1С
212 //-создаем частичную оплату от 1С
213 //-создаем шаблон оплаты согласно настройкам интеграции на оставшуюся сумму
214
215 $documentPayment = new PaymentCardDocument();
216 $documentPayment->setFields([
217 'ID_1C'=>$documentOrder->getField('ID_1C'),
218 'AMOUNT'=>abs($order->getPrice() - $paymentDocumentsPaidSum)
219
220 ]);
221 $documents[] = $documentPayment;
222 }
223
224 //endregion
225 }
226 }
227 else
228 {
229 //region 1. Из 1С не приходит оплат - в БУС шаблоны оплат не удаляем
230 if(!$hasPayment)
231 {
232 static::setConfig(static::DELETE_IF_NOT_FOUND_RELATED_PAYMENT_DOCUMENT, false);
233 }
234 //endregion
235 }
236 }
237 }
238 //TODO: доделать удаления оплат из списка документов оплат к импорту. И создания шаблона на всю оставшуюся сумму после импорта частичной оплаты от 1С
239
240 //endregion
241 }
242 return parent::convert($documents);
243 }
244
249 protected function deletePaymentDocumentNotPaid(array $documents)
250 {
251 $result=[];
252
253 foreach ($documents as $document)
254 {
255 if($this->isPaymentDocument($document))
256 {
257 if($this->documentIsPaid($document))
258 {
259 $result[] = $document;
260 }
261 }
262 else
263 {
264 $result[] = $document;
265 }
266 }
267
268 return $result;
269 }
270
275 protected function documentIsPaid(DocumentBase $document)
276 {
277 return ($document->getField('REK_VALUES')['1C_PAYED'] == 'Y');
278 }
279
284 protected function isPaymentDocument(DocumentBase $document)
285 {
286 return ($document->getTypeId() == static::getPaymentCardEntityTypeId()
287 || $document->getTypeId() == static::getPaymentCashLessEntityTypeId()
288 || $document->getTypeId() == static::getPaymentCashEntityTypeId());
289 }
290
291
292 protected function documentPaymentReplaceId(Order $order, $documents)
293 {
294 $result = new Result();
295
296 $paymentCollection = $order->getPaymentCollection();
297 $paymentIsReplace = false;
298
300 foreach($paymentCollection as $payment)
301 {
302 if(!$payment->isPaid())
303 {
305 foreach($this->getPaymentDocuments($documents) as $document)
306 {
307 if(
308 $payment->getSum() == (float)$document->getField('AMOUNT') &&
309 $this->resolveEntityTypeId($payment) == DocumentType::resolveID($document->getField('OPERATION'))
310 )
311 {
312 $document->setField('ID', $payment->getId());
313 $paymentIsReplace = true;
314 }
315 }
316 }
317 }
318
319 $result->setData(['IS_REPLACE'=>$paymentIsReplace]);
320
321 return $result;
322 }
323
328 protected function deletePaymentToReplace(Order $order, $documents)
329 {
330 $result = new Result();
331
332 $paymentCollection = $order->getPaymentCollection();
333 $paymentIsReplace = false;
334 $list = [];
335
336 foreach ($documents as $document)
337 {
338 if($this->isPaymentDocument($document))
339 {
340 $list[] = [
341 'AMOUNT'=>(float)$document->getField('AMOUNT'),
342 'OPERATION'=>DocumentType::resolveID($document->getField('OPERATION'))
343 ];
344 }
345 }
346
347 if(count($list)>0)
348 {
350 foreach($paymentCollection as $payment)
351 {
352 if(!$payment->isPaid())
353 {
354 foreach($list as $k=>$documentPayment)
355 {
356 //echo $this->resolveEntityTypeId($payment);
357
358 if(
359 $payment->getSum() == $documentPayment['AMOUNT'] &&
360 $this->resolveEntityTypeId($payment) == $documentPayment['OPERATION']
361 )
362 {
363 $r = $this->paymentDelete($payment);
364 if(!$r->isSuccess())
365 {
366 $result->addErrors($r->getErrors());
367 }
368 else
369 {
370 $paymentIsReplace = true;
371 }
372
373 unset($list[$k]);
374 }
375 }
376 }
377 }
378 }
379
380 if($result->isSuccess() && $paymentIsReplace)
381 $result->setData(['IS_REPLACE'=>true]);
382
383 return $result;
384 }
385
390 protected function hasPaymentDocuments(array $documents)
391 {
392 return ($this->hasDocumentByTypeId(static::getPaymentCardEntityTypeId(), $documents)
393 || $this->hasDocumentByTypeId(static::getPaymentCashLessEntityTypeId(), $documents)
394 || $this->hasDocumentByTypeId(static::getPaymentCashEntityTypeId(), $documents));
395 }
396
401 protected function getPaymentDocuments($documents)
402 {
403 $list = [];
404
405 foreach ($documents as $document)
406 {
407 if($this->isPaymentDocument($document))
408 {
409 $list[] = $document;
410 }
411 }
412 return $list;
413 }
414
419 protected function getPaymentDocumentsPaidSum($documents)
420 {
421 $sum = 0;
423 foreach ($this->getPaymentDocuments($documents) as $document)
424 {
425 //echo '<pre>';print_r($document->getFieldValues());
426 if($this->documentIsPaid($document))
427 {
428 $sum += (float)$document->getField('AMOUNT');
429 }
430 }
431 return $sum;
432 }
433
434 protected function orderPartiallyIsPaid(Order $order)
435 {
436 $paymentCollection = $order->getPaymentCollection();
438 {
440 foreach ($paymentCollection as $payment)
441 {
442 if($payment->isPaid())
443 return true;
444 }
445 }
446 return false;
447 }
448
454 {
455 $typeId = EntityType::UNDEFINED;
456
457 if(isset($fields['OPERATION']))
458 {
459 $typeId = EntityType::resolveID($fields['OPERATION']);
460 }
461 return $typeId;
462 }
463
470 protected function getItemByParam($key, array $items, array $params=null)
471 {
472 foreach ($items as $item)
473 {
474 if(array_key_exists($key, $item))
475 {
476 return $item;
477 }
478 }
479 return null;
480 }
481
486 protected function converterFactoryCreate($typeId)
487 {
488 return ConverterFactory::create($typeId);
489 }
490
495 protected function documentFactoryCreate($typeId)
496 {
497 return DocumentFactory::create($typeId);
498 }
499
504 protected function entityFactoryCreate($typeId)
505 {
506 return EntityImportFactory::create($typeId);
507 }
508}
$sum
Определения checkout.php:6
static resolveID($name)
Определения entitytype.php:59
const UNDEFINED
Определения entitytype.php:7
const ITEM_SERVICE
Определения importbase.php:11
convertDocument(DocumentBase $document)
Определения importonecbase.php:182
convert(array $documents)
Определения importonecpackage.php:113
getItemByParam($key, array $items, array $params=null)
Определения importonecsubordinatesale.php:470
static registerInstance($typeId, ISettingsImport $settings, ICollision $collision=null, ICriterion $criterion=null)
Определения managerimport.php:49
</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
Order
Определения order.php:6
$payment
Определения payment.php:14
$order
Определения payment.php:8
$paymentCollection
Определения payment.php:11
if(empty($signedUserToken)) $key
Определения quickway.php:257
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$items
Определения template.php:224
$k
Определения template_pdf.php:567