From a16c25291103ebc51b7028eef8d992ff634e1e8e Mon Sep 17 00:00:00 2001 From: fomichev Date: Tue, 10 Jun 2025 14:36:39 +0300 Subject: [PATCH] =?utf8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80?= =?utf8?q?=D0=B8=D0=BD=D0=B3=20=D0=B8=20=D0=BE=D1=80=D0=B3=D0=B0=D0=BD?= =?utf8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../AutoPlannogrammaController.php | 11 +- erp24/services/AutoPlannogrammaService.php | 169 +++++++++--------- erp24/services/StorePlanService.php | 4 +- 3 files changed, 92 insertions(+), 92 deletions(-) diff --git a/erp24/controllers/AutoPlannogrammaController.php b/erp24/controllers/AutoPlannogrammaController.php index 5f672918..791d0196 100644 --- a/erp24/controllers/AutoPlannogrammaController.php +++ b/erp24/controllers/AutoPlannogrammaController.php @@ -909,10 +909,7 @@ class AutoPlannogrammaController extends BaseController $filters['month'], $filters['year'], $goals, - $productSalesShare, - $filters['category'], - $filters['subcategory'], - $filters['species'] + $productSalesShare ); /* $matrixForecast = MatrixBouquetForecast::find() @@ -1035,11 +1032,7 @@ class AutoPlannogrammaController extends BaseController $filters['month'], $filters['year'], $goals, - $productSalesShare, - $filters['category'], - $filters['subcategory'], - $filters['species'] - + $productSalesShare ); $matrixForecast = MatrixBouquetForecast::find() diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index 0d7be355..cd70178f 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -1496,18 +1496,23 @@ class AutoPlannogrammaService ->all(); $productsIds = ArrayHelper::getColumn($products, 'id'); - if (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1342) { - $region = 52; - } elseif (CityStore::find()->where(['id' => $storeId])->one()->city_id == 1) { - $region = 77; - } else { - $region = null; + $storeParams = CityStoreParams::find() + ->where(['store_id' => $storeId]) + ->one(); + + $region = $storeParams?->address_region; + + if (!$region) { + $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); + $region = $cityId == 1 + ? BouquetComposition::REGION_MSK + : BouquetComposition::REGION_NN; } $priceRecords = PricesDynamic::find() ->select(['product_id', 'price']) ->where(['product_id' => $productsIds]) ->andWhere(['active' => 1]) - ->andWhere(['or', ['region_id' => $region], ['region_id' => null]]) + ->andWhere(['region_id' => $region]) ->indexBy('product_id') ->asArray() ->all(); @@ -1664,10 +1669,7 @@ class AutoPlannogrammaService $filters['month'], $year, $goals, - $productSalesShare, - $filters['category'], - $filters['subcategory'], - $filters['species'] + $productSalesShare ); @@ -1733,21 +1735,17 @@ class AutoPlannogrammaService */ public function getUnmarkedProductsComponents(int $storeId, string $month, string $year, int $regionId = null, $typeFilter = null): array { - $date = new \DateTimeImmutable(sprintf('%04d-%02d-01', $year, $month)); - - - $region = CityStoreParams::find() + $storeParams = CityStoreParams::find() ->where(['store_id' => $storeId]) - ->one()->address_region; + ->one(); + + $region = $storeParams?->address_region; - if (!$regionId && !$region) { - // определяем регион по городу + if (!$region && !$regionId) { $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); - if ($cityId == 1) { - $region = BouquetComposition::REGION_MSK; - } else { - $region = BouquetComposition::REGION_NN; - } + $region = $cityId == 1 + ? BouquetComposition::REGION_MSK + : BouquetComposition::REGION_NN; } $monthStart = sprintf('%04d-%02d-01 00:00:00', $year, $month); @@ -1819,8 +1817,6 @@ class AutoPlannogrammaService $priceDynamics = PricesDynamic::find() ->andWhere(['region_id' => $region]) ->andWhere(['product_id' => array_values( ArrayHelper::getColumn($nomenclatures, 'id') )]) - // ->andWhere(['<=', 'date_from', $monthStart]) - // ->andWhere(['>=', 'date_to', $monthEnd]) ->orderBy(['date_from' => SORT_DESC]) ->all(); @@ -1866,12 +1862,10 @@ class AutoPlannogrammaService public function calculateProductForecastInPiecesProductsWithHistory( int $storeId, - string $month, string $year, + string $month, + string $year, array $speciesGoals, - array $productSalesShare, - string $category = null, - string $subcategory = null, - string $species = null + array $productSalesShare ): array { $result = []; @@ -1881,16 +1875,25 @@ class AutoPlannogrammaService $goalsMap = $this->mapGoalsBySpecies($speciesGoals); - $region = CityStoreParams::find() + $storeParams = CityStoreParams::find() ->where(['store_id' => $storeId]) - ->one()->address_region ?? null; + ->one(); + + $region = $storeParams?->address_region; if (!$region) { $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); - $region = ($cityId == 1) + $region = $cityId == 1 ? BouquetComposition::REGION_MSK : BouquetComposition::REGION_NN; } + $priceRecords = PricesDynamic::find() + ->where([ + 'product_id' => array_keys($productSalesShare), + 'region_id' => $region, + 'active' => 1, + ]) + ->indexBy('product_id')->asArray()->all(); foreach ($productSalesShare as $productId => $data) { $share = $data['share'] ?? 0.0; @@ -1899,15 +1902,7 @@ class AutoPlannogrammaService continue; } - $priceRecord = PricesDynamic::find() - ->where([ - 'product_id' => $productId, - 'region_id' => $region, - 'active' => 1, - ]) - ->one(); - - if (!$priceRecord || $priceRecord->price <= 0) { + if (!$priceRecords[$productId] || $priceRecords[$productId]['price'] <= 0) { continue; } @@ -1915,6 +1910,7 @@ class AutoPlannogrammaService $cat = $data['category']; $sub = $data['subcategory']; $spec = $data['species']; + $price = $priceRecords[$productId]['price']; if ( ! isset( $goalsMap[$storeId], @@ -1923,7 +1919,6 @@ class AutoPlannogrammaService $goalsMap[$storeId][$cat][$sub][$spec] ) ) { - continue; } @@ -1931,7 +1926,7 @@ class AutoPlannogrammaService $forecastSum = $goal * $share; - $forecastCount = $forecastSum / $priceRecord->price; + $forecastCount = $forecastSum / $price; $result[] = [ 'month' => $month, @@ -1939,7 +1934,7 @@ class AutoPlannogrammaService 'product_id' => $productId, 'goal' => $goal, 'goal_share' => round($forecastSum, 2), - 'price' => $priceRecord->price, + 'price' => $price, 'forecast_pieces' => round($forecastCount), 'store_id' => $data['store_id'], 'category' => $data['category'], @@ -2131,7 +2126,7 @@ class AutoPlannogrammaService * @param array|int $storeIds * @param int $month * @param int $year - * @param int $regionId + * @param string $type * @return array список строк с полями: * sale_id, sale_date, product_id, product_name, * component_guid, component_name, component_category, @@ -2139,9 +2134,11 @@ class AutoPlannogrammaService */ public function getProductsComponentsInCategory(int $storeId, string $month, string $year, string $type = self::TYPE_SALES): array { - $region = CityStoreParams::find() + $storeParams = CityStoreParams::find() ->where(['store_id' => $storeId]) - ->one()->address_region ?? null; + ->one(); + + $region = $storeParams?->address_region; if (!$region) { $cityId = CityStore::find()->select('city_id')->where(['id' => $storeId])->scalar(); @@ -2224,8 +2221,8 @@ class AutoPlannogrammaService $componentProducts = $writeOffsProducts; } - $components = []; - $rows = []; + $componentGuids = []; + $componentDataRecords = []; foreach ($componentProducts as $cp) { $js = trim($cp['components']); if ($js === '' || $js[0] !== '{') { @@ -2240,8 +2237,8 @@ class AutoPlannogrammaService if ($qty <= 0) { continue; } - $components[$guid] = true; - $rows[] = [ + $componentGuids[$guid] = true; + $componentDataRecords[] = [ 'record_id' => $cp['id'] ?? $cp['write_off_id'], 'sale_date' => $cp['date'] ?? $cp['write_off_date'], 'product_id' => $cp['product_id'], @@ -2255,11 +2252,11 @@ class AutoPlannogrammaService } } - if (empty($rows)) { + if (empty($componentDataRecords)) { return []; } - $guids = array_keys($components); + $guids = array_keys($componentGuids); $nomenclatures = Products1cNomenclature::find() ->andWhere(['id' => $guids]) ->andWhere(['not in', 'category', ['', 'букет', 'сборка', 'сервис']]) @@ -2273,49 +2270,59 @@ class AutoPlannogrammaService ->all(); $pricesByProduct = []; - foreach ($priceDynamics as $pd) { - $pricesByProduct[$pd->product_id][] = $pd; + foreach ($priceDynamics as $priceRecord) { + $pricesByProduct[$priceRecord->product_id][] = $priceRecord; } $result = []; - foreach ($rows as $r) { - $guid = $r['component_guid']; - $n = $nomenclatures[$guid] ?? null; - $pid = $n?->id; + + foreach ($componentDataRecords as $componentDataRecord) { + $guid = $componentDataRecord['component_guid']; + $nomenclatureData = $nomenclatures[$guid] ?? null; + $productId = $nomenclatureData?->id; $price = 0; - foreach ($pricesByProduct[$pid] ?? [] as $pd) { - if ($pd->date_from <= $r['sale_date'] && $pd->date_to >= $r['sale_date']) { - if ($pid == '2b72702a-792f-11e8-9edd-1c6f659fb563') { - $price = 8.66; // TODO: заглушка для цены гелия - исправить - } else { - $price = $pd->price; + $dailyPrices = []; + foreach ($pricesByProduct[$productId] ?? [] as $priceRecordForProduct) { + if ($productId == '2b72702a-792f-11e8-9edd-1c6f659fb563') { + $saleDay = (new \DateTime($componentDataRecord['sale_date']))->format('Y-m-d'); + $fromDay = (new \DateTime($priceRecordForProduct->date_from))->modify('-1 day')->format('Y-m-d'); + $toDay = (new \DateTime($priceRecordForProduct->date_to ))->modify('+1 day')->format('Y-m-d'); + + if ($fromDay <= $saleDay && $saleDay <= $toDay) { + $dailyPrices[] = (float)$priceRecordForProduct->price; } - - + } + if ($priceRecordForProduct->date_from <= $componentDataRecord['sale_date'] && $priceRecordForProduct->date_to >= $componentDataRecord['sale_date']) { + $price = $priceRecordForProduct->price; break; } } - $cost = $r['quantity'] * $price * $r['quantity_product']; - $costComponent = $r['quantity'] * $price; + if (!empty($dailyPrices)) { + $price = min($dailyPrices); + } else { + $price = 0.0; + } + $cost = $componentDataRecord['quantity'] * $price * $componentDataRecord['quantity_product']; + $costComponent = $componentDataRecord['quantity'] * $price; $result[] = [ 'store_id' => $storeId, - 'record_id' => $r['record_id'], - 'sale_date' => $r['sale_date'], - 'product_id' => $r['product_id'], - 'product_name' => $r['product_name'], - 'quantity_product' => $r['quantity_product'], + 'record_id' => $componentDataRecord['record_id'], + 'sale_date' => $componentDataRecord['sale_date'], + 'product_id' => $componentDataRecord['product_id'], + 'product_name' => $componentDataRecord['product_name'], + 'quantity_product' => $componentDataRecord['quantity_product'], 'component_guid' => $guid, - 'component_name' => $n?->name, - 'component_category' => $n?->category, - 'component_subcategory'=> $n?->subcategory, - 'component_species' => $n?->species, - 'quantity' => $r['quantity'], + 'component_name' => $nomenclatureData?->name, + 'component_category' => $nomenclatureData?->category, + 'component_subcategory'=> $nomenclatureData?->subcategory, + 'component_species' => $nomenclatureData?->species, + 'quantity' => $componentDataRecord['quantity'], 'price' => $price, 'cost' => $cost, 'component_cost' => $costComponent, 'type' => $type, - 'operation' => $r['operation'], + 'operation' => $componentDataRecord['operation'], ]; } diff --git a/erp24/services/StorePlanService.php b/erp24/services/StorePlanService.php index 8ae90891..6c9792ed 100755 --- a/erp24/services/StorePlanService.php +++ b/erp24/services/StorePlanService.php @@ -252,7 +252,7 @@ class StorePlanService * ] * ] */ - public static function calculateHistoricalShare($storeId, $selectedMonth, $selectedYear, $category, $subcategory = null, $species = null) + public static function calculateHistoricalShare($storeId, $selectedMonth, $selectedYear, $category = null, $subcategory = null, $species = null) { $baseDate = strtotime("{$selectedYear}-{$selectedMonth}-01"); @@ -996,7 +996,7 @@ class StorePlanService $productsData = []; $globalTotal = 0; - // var_dump($productsWithHistory); die(); + foreach ($productsWithHistory as $product) { $guid = $product['guid']; $result = self::processProductWithHistory($storeId, $product, $weightedPeriods); -- 2.39.5