Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
storestockquantity.php
1<?php
2
4
11
14{
15 protected const DEFAULT_DATE_INTERVAL = '-30D';
16
23 public static function getOutgoingQuantityForStores(array $userFilter = []): array
24 {
25 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter);
26
27 $reduceCallback = static function($result, $current)
28 {
29 $measureId = (int)$current['MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(true)['ID'];
30 if (!array_key_exists($measureId, $result))
31 {
32 $result[$measureId] = 0.0;
33 }
34
35 $result[$measureId] += $current['AMOUNT']['OUTGOING'];
36 return $result;
37 };
38
39 foreach ($receivedQuantity as $storeId => $productEntry)
40 {
41 $receivedQuantity[$storeId] = array_reduce($productEntry, $reduceCallback, []);
42 }
43
44 return $receivedQuantity;
45 }
46
47
53 public static function getOutgoingQuantityForProducts(array $userFilter = []): array
54 {
55 $result = [];
56 $userFilter['ONLY_EXTERNAL_INCOMING'] = true;
57 foreach (self::getIncomingOutgoingQuantitiesFromDocuments($userFilter) as $entries)
58 {
59 foreach ($entries as $productId => $fields)
60 {
61 $result[$productId] ??= 0;
62 $result[$productId] += (float)($fields['AMOUNT']['OUTGOING'] ?? 0);
63 }
64 }
65
66 return $result;
67 }
68
76 public static function getOutgoingQuantityForProductsOnStore(int $storeId, array $userFilter = []): array
77 {
78 $userFilter['STORES'] = $storeId;
79
80 $outgoingQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter)[$storeId] ?? [];
81
82 return array_map(fn(array $entry) => $entry['AMOUNT']['OUTGOING'], $outgoingQuantity);
83 }
84
91 public static function getReceivedQuantityForStores(array $userFilter = []): array
92 {
93 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter);
94
95 $reduceCallback = static function($result, $current)
96 {
97 $measureId = (int)$current['MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(true)['ID'];
98 if (!array_key_exists($measureId, $result))
99 {
100 $result[$measureId] = 0.0;
101 }
102
103 $result[$measureId] += $current['AMOUNT']['INCOMING'];
104 return $result;
105 };
106
107 foreach ($receivedQuantity as $storeId => $productEntry)
108 {
109 $receivedQuantity[$storeId] = array_reduce($productEntry, $reduceCallback, []);
110 }
111
112 return $receivedQuantity;
113 }
114
120 public static function getReceivedQuantityForProducts(array $userFilter = []): array
121 {
122 $result = [];
123
124 $userFilter['ONLY_EXTERNAL_INCOMING'] = true;
125 foreach (self::getIncomingOutgoingQuantitiesFromDocuments($userFilter) as $entries)
126 {
127 foreach ($entries as $productId => $fields)
128 {
129 $result[$productId] ??= 0;
130 $result[$productId] += (float)($fields['AMOUNT']['INCOMING'] ?? 0);
131 }
132 }
133
134 return $result;
135 }
136
145 public static function getReceivedQuantityForProductsOnStore(int $storeId, array $userFilter = []): array
146 {
147 $userFilter['STORES'] = $storeId;
148
149 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter)[$storeId] ?? [];
150
151 return array_map(fn(array $entry) => $entry['AMOUNT']['INCOMING'], $receivedQuantity);
152 }
153
163 private static function getIncomingOutgoingQuantitiesFromDocuments(array $userFilter = []): array
164 {
165 $userFilter = self::prepareFilter($userFilter);
166
167 $productsDataList = self::getDocumentProductsDataList($userFilter);
168
169 $result = [];
170
171 while ($entry = $productsDataList->fetch())
172 {
173 $storeFromId = (int)$entry['STORE_FROM'];
174 $storeToId = (int)$entry['STORE_TO'];
175
176 if (!isset($result[$storeFromId]))
177 {
178 $result[$storeFromId] = [];
179 }
180 if (!isset($result[$storeToId]))
181 {
182 $result[$storeToId] = [];
183 }
184
185 $productId = $entry['ELEMENT_ID'];
186 if (!array_key_exists($productId, $result[$storeToId]))
187 {
188 $result[$storeToId][$productId] = [
189 'MEASURE_ID' => (int)$entry['MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(true)['ID'],
190 'AMOUNT' => [
191 'INCOMING' => 0.0,
192 'OUTGOING' => 0.0,
193 ],
194 ];
195 }
196
197 if ($storeFromId > 0)
198 {
199 $result[$storeFromId][$productId]['AMOUNT']['OUTGOING'] += (float)$entry['AMOUNT_SUM'];
200 }
201
202 if ($storeToId > 0)
203 {
204 $result[$storeToId][$productId]['AMOUNT']['INCOMING'] += (float)$entry['AMOUNT_SUM'];
205 }
206 }
207
208 return $result;
209 }
210
215 private static function getDocumentProductsDataList(array $userFilter = []): Result
216 {
217 $receivedQuantityQuery = new Query(StoreDocumentElementTable::getEntity());
218 $receivedQuantityQuery->setSelect([
219 'DOCUMENT.DOC_TYPE',
220 'STORE_FROM',
221 'STORE_TO',
222 'ELEMENT_ID',
223 'AMOUNT_SUM',
224 'MEASURE_ID' => 'PRODUCT.MEASURE'
225 ]);
226
227 $filter = [
228 '=DOCUMENT.STATUS' => 'Y',
229 ];
230
231 if (isset($userFilter['PRODUCTS']))
232 {
233 $filter['=ELEMENT_ID'] = $userFilter['PRODUCTS'];
234 }
235
236 if (isset($userFilter['STORES']))
237 {
238 $filter[] = [
239 'LOGIC' => 'OR',
240 '=STORE_TO' => $userFilter['STORES'],
241 '=STORE_FROM' => $userFilter['STORES'],
242 ];
243 }
244 elseif (isset($userFilter['ONLY_EXTERNAL_INCOMING']))
245 {
246 $filter['!DOCUMENT.DOC_TYPE'] = StoreDocumentTable::TYPE_MOVING;
247 }
248
249 if (isset($userFilter['REPORT_INTERVAL']))
250 {
251 $filter['>=DOCUMENT.DATE_STATUS'] = new DateTime($userFilter['REPORT_INTERVAL']['FROM']);
252 $filter['<=DOCUMENT.DATE_STATUS'] = new DateTime($userFilter['REPORT_INTERVAL']['TO']);
253 }
254
255 $receivedQuantityQuery->setFilter($filter);
256 $receivedQuantityQuery->setGroup(['STORE_FROM', 'STORE_TO', 'ELEMENT_ID']);
257 $receivedQuantityQuery->registerRuntimeField(
258 new ExpressionField('AMOUNT_SUM', 'SUM(de.AMOUNT)')
259 );
260 $receivedQuantityQuery->setCustomBaseTableAlias('de');
261
262 return $receivedQuantityQuery->exec();
263 }
264
268 private static function getDefaultReportInterval(): array
269 {
270 $currentDate = new DateTime();
271 $intervalStartDate = new DateTime();
272 $intervalStartDate->add(self::DEFAULT_DATE_INTERVAL);
273
274 return [
275 'FROM' => $intervalStartDate->toString(),
276 'TO' => $currentDate->toString(),
277 ];
278 }
279
284 private static function prepareFilter(array $filter): array
285 {
286 if (!isset($filter['REPORT_INTERVAL']['FROM'], $filter['REPORT_INTERVAL']['TO']))
287 {
288 $filter['REPORT_INTERVAL'] = self::getDefaultReportInterval();
289 }
290
291 return $filter;
292 }
293}
static getReceivedQuantityForProductsOnStore(int $storeId, array $userFilter=[])
static getOutgoingQuantityForProductsOnStore(int $storeId, array $userFilter=[])