Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
fifo.php
1<?php
3
4use Bitrix\Catalog\EO_StoreBatch;
10
16final class Fifo extends Base
17{
18 public function fill(): Result
19 {
20 $result = new Result();
21
22 $sortedItems = new ElementBatchTree();
23 $negativeStoreItems = [];
25 foreach ($this->elementBatchTree as $entity)
26 {
27 $element = $entity->getElement();
28 $storeConditions = $this->getStoreConditions($entity);
29 if ($entity->isArrivalElement())
30 {
31 $newBatch = new EO_StoreBatch();
32 $newBatch->setStoreId($entity->getStoreId());
33 $newBatch->setAvailableAmount($entity->getAmount());
34 $newBatch->setElementId($this->balancer->getProductId());
35 $newBatch->setPurchasingPrice($element->getBatchPrice());
36 $newBatch->setPurchasingCurrency($element->getBatchCurrency());
37 $newStoreItem = new Entity\StoreItem($newBatch);
38 $storeConditions[$newStoreItem->getHash()] = $newStoreItem;
39 $entity->setStoreItemHash($newStoreItem->getHash());
40 $sortedItems->push($entity);
41
42 $negativeStoreItem = $negativeStoreItems[$entity->getStoreId()] ?? null;
43 if (!empty($negativeStoreItem))
44 {
46 foreach ($negativeStoreItem as $key => $negativeItem)
47 {
48 if ($negativeItem->getStoreId() !== $entity->getStoreId())
49 {
50 continue;
51 }
52
53 foreach ($storeConditions as $storeCondition)
54 {
55 $currentStock = $storeCondition->getStoreBatch()->getAvailableAmount() - $negativeItem->getAmount();
56 $resortedEntity = new Entity\ElementBatchItem(
57 clone($negativeItem->getElement()),
58 $negativeItem->getStoreId()
59 );
60 $element = $resortedEntity->getElement();
61 $element->setBatchPrice($storeCondition->getStoreBatch()->getPurchasingPrice());
62 $element->setBatchCurrency($storeCondition->getStoreBatch()->getPurchasingCurrency());
63 $resortedEntity->setStoreItemHash($storeCondition->getHash());
64 if ($currentStock >= 0)
65 {
66 $sortedItems->push($resortedEntity);
67 $storeCondition->getStoreBatch()->setAvailableAmount($currentStock);
68
69 unset($negativeStoreItem[$key]);
70 }
71 else
72 {
73 $element->setAmount($storeCondition->getStoreBatch()->getAvailableAmount());
74 $sortedItems->push($resortedEntity);
75
76 $storeCondition->getStoreBatch()->setAvailableAmount(0);
77
78 $negativeItem->getElement()->setAmount(-$currentStock);
79 }
80 }
81 }
82 }
83 }
84 else
85 {
86 $fullCompleted = false;
88 foreach ($storeConditions as $storeCondition)
89 {
90 $batch = $storeCondition->getStoreBatch();
91 if ($batch->getAvailableAmount() <= 0)
92 {
93 continue;
94 }
95
96 $currentStock = $batch->getAvailableAmount() - $entity->getAmount();
97 if ($currentStock >= 0)
98 {
99 $batch->setAvailableAmount($currentStock);
100 $entity->setStoreItemHash($storeCondition->getHash());
101 $element->setBatchPrice($storeCondition->getStoreBatch()->getPurchasingPrice());
102 $element->setBatchCurrency($storeCondition->getStoreBatch()->getPurchasingCurrency());
103 $sortedItems->push($entity);
104 $fullCompleted = true;
105
106 break;
107 }
108 else
109 {
110 $newBinding = new Entity\ElementBatchItem(clone($element), $entity->getStoreId());
111 $newBinding->setStoreItemHash($storeCondition->getHash());
112 $newElement = $newBinding->getElement();
113 $newElement->setAmount(-$batch->getAvailableAmount());
114 $newElement->setBatchPrice($storeCondition->getStoreBatch()->getPurchasingPrice());
115 $newElement->setBatchCurrency($storeCondition->getStoreBatch()->getPurchasingCurrency());
116 $sortedItems->push($newBinding);
117 $batch->setAvailableAmount(0);
118 $element->setAmount($currentStock);
119 }
120 }
121
122 if (!$fullCompleted)
123 {
124 $negativeItem = clone($entity);
125 $negativeStoreItems[$negativeItem->getStoreId()] ??= [];
126 $negativeStoreItems[$negativeItem->getStoreId()] = $negativeItem;
127 }
128 }
129
130 $this->setStoreConditions($entity->getStoreId(), $storeConditions);
131 }
132
133 $oldBatchIds = [];
134 $oldBatches= StoreBatchTable::getList([
135 'filter' => ['=ELEMENT_ID' => $this->balancer->getProductId()],
136 'select' => ['ID'],
137 ]);
138
139 while ($batch = $oldBatches->fetch())
140 {
141 $oldBatchIds[] = $batch['ID'];
142 StoreBatchTable::delete($batch['ID']);
143 }
144
146 'filter' => ['=PRODUCT_BATCH_ID' => $oldBatchIds],
147 'select' => ['ID'],
148 ]);
149
150 while ($binding = $oldBindings->fetch())
151 {
153 }
154
155 foreach ($this->storeConditions as $storeCondition)
156 {
157 foreach ($storeCondition as $item)
158 {
159 $result = $item->save();
160 if (!$result->isSuccess())
161 {
162 return $result;
163 }
164 }
165 }
166
168 foreach ($sortedItems as $item)
169 {
170 if (isset($this->storeConditions[$item->getStoreId()][$item->getStoreItemHash()]))
171 {
173 $storeItem = $this->storeConditions[$item->getStoreId()][$item->getStoreItemHash()];
174 $item->getElement()->setProductBatchId($storeItem->getStoreBatch()->getId());
175 $result = $item->save();
176 if (!$result->isSuccess())
177 {
178 return $result;
179 }
180 }
181 }
182
183 return $result;
184 }
185
186 private function getStoreConditions(Entity\ElementBatchItem $entity): array
187 {
188 if (isset($this->storeConditions[$entity->getStoreId()]))
189 {
190 return $this->storeConditions[$entity->getStoreId()];
191 }
192
193 $this->storeConditions[$entity->getStoreId()] = [];
194
195 return $this->storeConditions[$entity->getStoreId()];
196 }
197
198 private function setStoreConditions(int $storeId, array $storeConditions): void
199 {
200 $this->storeConditions[$storeId] ??= [];
201 $this->storeConditions[$storeId] = $storeConditions;
202 }
203}
static getList(array $parameters=array())