25 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter);
27 $reduceCallback =
static function($result, $current)
29 $measureId = (int)$current[
'MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(
true)[
'ID'];
30 if (!array_key_exists($measureId, $result))
32 $result[$measureId] = 0.0;
35 $result[$measureId] += $current[
'AMOUNT'][
'OUTGOING'];
39 foreach ($receivedQuantity as $storeId => $productEntry)
41 $receivedQuantity[$storeId] = array_reduce($productEntry, $reduceCallback, []);
44 return $receivedQuantity;
56 $userFilter[
'ONLY_EXTERNAL_INCOMING'] =
true;
57 foreach (self::getIncomingOutgoingQuantitiesFromDocuments($userFilter) as $entries)
59 foreach ($entries as $productId => $fields)
61 $result[$productId] ??= 0;
62 $result[$productId] += (float)($fields[
'AMOUNT'][
'OUTGOING'] ?? 0);
78 $userFilter[
'STORES'] = $storeId;
80 $outgoingQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter)[$storeId] ?? [];
82 return array_map(fn(array $entry) => $entry[
'AMOUNT'][
'OUTGOING'], $outgoingQuantity);
93 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter);
95 $reduceCallback =
static function($result, $current)
97 $measureId = (int)$current[
'MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(
true)[
'ID'];
98 if (!array_key_exists($measureId, $result))
100 $result[$measureId] = 0.0;
103 $result[$measureId] += $current[
'AMOUNT'][
'INCOMING'];
107 foreach ($receivedQuantity as $storeId => $productEntry)
109 $receivedQuantity[$storeId] = array_reduce($productEntry, $reduceCallback, []);
112 return $receivedQuantity;
124 $userFilter[
'ONLY_EXTERNAL_INCOMING'] =
true;
125 foreach (self::getIncomingOutgoingQuantitiesFromDocuments($userFilter) as $entries)
127 foreach ($entries as $productId => $fields)
129 $result[$productId] ??= 0;
130 $result[$productId] += (float)($fields[
'AMOUNT'][
'INCOMING'] ?? 0);
147 $userFilter[
'STORES'] = $storeId;
149 $receivedQuantity = self::getIncomingOutgoingQuantitiesFromDocuments($userFilter)[$storeId] ?? [];
151 return array_map(fn(array $entry) => $entry[
'AMOUNT'][
'INCOMING'], $receivedQuantity);
163 private static function getIncomingOutgoingQuantitiesFromDocuments(array $userFilter = []): array
165 $userFilter = self::prepareFilter($userFilter);
167 $productsDataList = self::getDocumentProductsDataList($userFilter);
171 while ($entry = $productsDataList->fetch())
173 $storeFromId = (int)$entry[
'STORE_FROM'];
174 $storeToId = (int)$entry[
'STORE_TO'];
176 if (!isset($result[$storeFromId]))
178 $result[$storeFromId] = [];
180 if (!isset($result[$storeToId]))
182 $result[$storeToId] = [];
185 $productId = $entry[
'ELEMENT_ID'];
186 if (!array_key_exists($productId, $result[$storeToId]))
188 $result[$storeToId][$productId] = [
189 'MEASURE_ID' => (int)$entry[
'MEASURE_ID'] ?: \CCatalogMeasure::getDefaultMeasure(true)[
'ID'],
197 if ($storeFromId > 0)
199 $result[$storeFromId][$productId][
'AMOUNT'][
'OUTGOING'] += (float)$entry[
'AMOUNT_SUM'];
204 $result[$storeToId][$productId][
'AMOUNT'][
'INCOMING'] += (float)$entry[
'AMOUNT_SUM'];
215 private static function getDocumentProductsDataList(array $userFilter = []): Result
218 $receivedQuantityQuery->setSelect([
224 'MEASURE_ID' =>
'PRODUCT.MEASURE'
228 '=DOCUMENT.STATUS' =>
'Y',
231 if (isset($userFilter[
'PRODUCTS']))
233 $filter[
'=ELEMENT_ID'] = $userFilter[
'PRODUCTS'];
236 if (isset($userFilter[
'STORES']))
240 '=STORE_TO' => $userFilter[
'STORES'],
241 '=STORE_FROM' => $userFilter[
'STORES'],
244 elseif (isset($userFilter[
'ONLY_EXTERNAL_INCOMING']))
249 if (isset($userFilter[
'REPORT_INTERVAL']))
251 $filter[
'>=DOCUMENT.DATE_STATUS'] =
new DateTime($userFilter[
'REPORT_INTERVAL'][
'FROM']);
252 $filter[
'<=DOCUMENT.DATE_STATUS'] =
new DateTime($userFilter[
'REPORT_INTERVAL'][
'TO']);
255 $receivedQuantityQuery->setFilter($filter);
256 $receivedQuantityQuery->setGroup([
'STORE_FROM',
'STORE_TO',
'ELEMENT_ID']);
257 $receivedQuantityQuery->registerRuntimeField(
258 new ExpressionField(
'AMOUNT_SUM',
'SUM(de.AMOUNT)')
260 $receivedQuantityQuery->setCustomBaseTableAlias(
'de');
262 return $receivedQuantityQuery->exec();
268 private static function getDefaultReportInterval(): array
270 $currentDate =
new DateTime();
271 $intervalStartDate =
new DateTime();
272 $intervalStartDate->add(self::DEFAULT_DATE_INTERVAL);
275 'FROM' => $intervalStartDate->toString(),
276 'TO' => $currentDate->toString(),
284 private static function prepareFilter(array $filter): array
286 if (!isset($filter[
'REPORT_INTERVAL'][
'FROM'], $filter[
'REPORT_INTERVAL'][
'TO']))
288 $filter[
'REPORT_INTERVAL'] = self::getDefaultReportInterval();