From f0e6658a6bc57cb939a02aef50462a1af804453c Mon Sep 17 00:00:00 2001 From: marina Date: Fri, 18 Apr 2025 14:27:09 +0300 Subject: [PATCH] =?utf8?q?ERP-359=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D1=82?= =?utf8?q?=D1=8C=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D1=80=D0=B0?= =?utf8?q?=D1=81=D1=87=D0=B5=D1=82=D0=B0=20=D0=BD=D0=B0=20=D0=BC=D0=B5?= =?utf8?q?=D1=81=D1=8F=D1=86=20-=20=D1=81=D1=83=D0=BC=D0=BC=D0=B0=20=D0=BF?= =?utf8?q?=D1=80=D0=BE=D0=B4=D0=B0=D0=B6=20=D0=B2=D0=B8=D0=B4=D0=B0=20?= =?utf8?q?=D0=B4=D0=BB=D1=8F=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BF=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../controllers/AutoPlanogrammaController.php | 113 +++--- erp24/services/AutoPlannogrammaService.php | 328 +++++++++++------- .../{test-sales.php => calculating.php} | 0 .../{sales.php => control.php} | 0 4 files changed, 268 insertions(+), 173 deletions(-) rename erp24/views/auto-planogramma/{test-sales.php => calculating.php} (100%) rename erp24/views/auto-planogramma/{sales.php => control.php} (100%) diff --git a/erp24/controllers/AutoPlanogrammaController.php b/erp24/controllers/AutoPlanogrammaController.php index 4af47320..bbbb297b 100644 --- a/erp24/controllers/AutoPlanogrammaController.php +++ b/erp24/controllers/AutoPlanogrammaController.php @@ -69,7 +69,7 @@ class AutoPlanogrammaController extends BaseController ]); } - public function actionTestSales() + public function actionCalculating() { $request = Yii::$app->request; @@ -90,62 +90,50 @@ class AutoPlanogrammaController extends BaseController ]); if (!empty($filters['plan_date'])) { + $filters = [ + 'category' => $request->get('category'), + 'subcategory' => $request->get('subcategory'), + 'product_name' => $request->get('product_name'), + 'store_id' => $request->get('store_id'), + 'plan_date' => $request->get('plan_date'), + 'type' => $request->get('type'), + ]; - $datePlan = $filters['plan_date']; - $dateFromForCategory = date('Y-m-d', strtotime($datePlan . ' -12 months')); - $dateFrom = date('Y-m-d', strtotime($datePlan . ' -3 months')); - - $autoPlannogrammaService = new AutoPlannogrammaService(); - - $monthCategoryShare = $autoPlannogrammaService->getMonthCategoryShare($dateFromForCategory); - $monthCategoryGoal = $autoPlannogrammaService->getMonthCategoryGoal($monthCategoryShare, $datePlan); - $monthSubcategoryShare = $autoPlannogrammaService->getMonthSubcategoryShare($dateFrom, $datePlan); - $monthSubcategoryGoal = $autoPlannogrammaService->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); - $monthSpeciesShare = $autoPlannogrammaService->getMonthSpeciesShare($dateFrom, $datePlan); - $monthSpeciesGoalDirtry = $autoPlannogrammaService->getMonthSpeciesGoalDirtry($monthSpeciesShare, $monthSubcategoryGoal); - - - $filtered = array_filter($monthSpeciesGoalDirtry, function ($row) use ($filters) { - foreach ($filters as $key => $value) { - if ($value !== null && $value !== '' && isset($row[$key]) && stripos($row[$key], $value) === false) { - return false; - } - } - return true; - }); + $service = new AutoPlannogrammaService(); $dataProvider = new ArrayDataProvider([ - 'allModels' => array_values($filtered), + 'allModels' => $service->calculateFullGoalChain($filters), 'pagination' => [ 'pageSize' => 100 ], ]); + } - return $this->render('test-sales', [ + return $this->render('calculating', [ 'dataProvider' => $dataProvider, 'filters' => $filters, ]); } - public function actionSales() + public function actionControl() { $filters = Yii::$app->request->get(); - $params = []; + $conditions = []; if (!empty($filters['product_name'])) { - $conditions[] = 'p1.name LIKE :product_name'; + $conditions[] = 'p1n.name LIKE :product_name'; $params[':product_name'] = '%' . $filters['product_name'] . '%'; } if (!empty($filters['category'])) { - $conditions[] = 'p1.category = :category'; + $conditions[] = 'p1n.category = :category'; $params[':category'] = $filters['category']; } if (!empty($filters['subcategory'])) { - $conditions[] = 'p1.subcategory = :subcategory'; + $conditions[] = 'p1n.subcategory = :subcategory'; $params[':subcategory'] = $filters['subcategory']; } @@ -155,33 +143,51 @@ class AutoPlanogrammaController extends BaseController } if (!empty($filters['plan_date'])) { - // Преобразуем дату в формат Y-m-d $date = \DateTime::createFromFormat('d-m-Y', $filters['plan_date']); if ($date) { $startDate = $date->format('Y-m-d'); $endDate = $date->modify('+1 month')->format('Y-m-d'); - $conditions[] = 'DATE(s.date) >= :start_date'; - $conditions[] = 'DATE(s.date) < :end_date'; + if ($filters['type'] === 'writeOffs') { + $conditions[] = 'DATE(w.date) >= :start_date'; + $conditions[] = 'DATE(w.date) < :end_date'; + } else { + $conditions[] = 'DATE(s.date) >= :start_date'; + $conditions[] = 'DATE(s.date) < :end_date'; + } $params[':start_date'] = $startDate; $params[':end_date'] = $endDate; } } - if (!empty($filters['type'])) { - $conditions[] = 's.type = :type'; - $params[':type'] = $filters['type']; - } - - $where = implode(' AND ', $conditions); - - $query = Yii::$app->db->createCommand(" + $where = !empty($conditions) ? 'WHERE ' . implode(' AND ', $conditions) : ''; + if (isset($filters['type']) && $filters['type'] == 'writeOffs') { + $query = Yii::$app->db->createCommand(" + SELECT + c.name AS city_name, + p1n.category, + p1n.subcategory, + item ->> 'product_id' AS product_id, + p1n.name AS product_name, + SUM(CAST(item ->> 'quantity' AS NUMERIC)) AS count, + SUM(CAST(item ->> 'summ' AS NUMERIC)) AS sum + FROM write_offs w + JOIN export_import_table ex ON ex.export_val = w.store_id + JOIN city_store c ON c.id = ex.entity_id + JOIN LATERAL jsonb_array_elements(w.items::jsonb) AS item ON true + LEFT JOIN products_1c_nomenclature p1n ON p1n.id = item ->> 'product_id' + $where + GROUP BY w.store_id, c.name, p1n.category, p1n.subcategory, product_id, p1n.name + ORDER BY w.store_id, p1n.category, p1n.subcategory, p1n.name + ")->bindValues($params)->queryAll(); + } else { + $query = Yii::$app->db->createCommand(" SELECT c.name AS city_name, - p1.name AS product_name, - p1.category, - p1.subcategory, + p1n.name AS product_name, + p1n.category, + p1n.subcategory, SUM(CASE WHEN s.operation = 'Продажа' THEN sp.quantity WHEN s.operation = 'Возврат' THEN -sp.quantity @@ -194,29 +200,22 @@ class AutoPlanogrammaController extends BaseController END) AS sum FROM sales s LEFT JOIN sales_products sp ON sp.check_id = s.id - LEFT JOIN products_1c_nomenclature p1 ON p1.id = sp.product_id + LEFT JOIN products_1c_nomenclature p1n ON p1n.id = sp.product_id LEFT JOIN export_import_table ex ON ex.export_val = store_id_1c LEFT JOIN city_store c ON c.id = entity_id - WHERE $where - GROUP BY p1.name, p1.category, p1.subcategory, c.name, c.id - ORDER BY c.id DESC, category, subcategory, p1.name + $where + GROUP BY p1n.name, p1n.category, p1n.subcategory, c.name, c.id + ORDER BY c.id DESC, category, subcategory, p1n.name ")->bindValues($params)->queryAll(); - + } $dataProvider = new ArrayDataProvider([ 'allModels' => $query, 'pagination' => ['pageSize' => 20], ]); - return $this->render('sales', [ + return $this->render('control', [ 'dataProvider' => $dataProvider, 'filters' => $filters, ]); - } - - public function actionTestWriteOffs() - { - return $this->render('test-write-offs'); - } - } \ No newline at end of file diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index 6fd32f13..d40263d8 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -4,6 +4,7 @@ namespace yii_app\services; use yii\db\Expression; use yii\db\Query; +use yii\helpers\ArrayHelper; use yii_app\records\CityStore; use yii_app\records\SalesWriteOffsPlan; @@ -14,72 +15,101 @@ class AutoPlannogrammaService return CityStore::findAll(['visible' => CityStore::IS_VISIBLE]); } - private function getStoreSalesTotals(array $storeIds, string $dateFrom, $productFilter = null): array + public function getStoreTotals(array $storeIds, string $dateFrom, ?array $productFilter = null, string $type = 'sales', ?string $dateTo = null): array { $query = (new Query()) ->select([ 'store_id' => 'ex.entity_id', - 'total_sum' => new Expression(" - SUM(CASE - WHEN s.operation = 'Продажа' THEN sp.summ - WHEN s.operation = 'Возврат' THEN -sp.summ - ELSE 0 - END) - ") + 'total_sum' => new Expression( + $type === 'writeOffs' + ? 'SUM(CAST(item ->> \'summ\' AS NUMERIC))' + : 'SUM(sp.summ)' + ) ]) - ->from(['s' => 'sales']) - ->leftJoin('sales_products sp', 'sp.check_id = s.id') - ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') - ->where(['>=', 's.date', $dateFrom]) - ->andWhere(['ex.entity_id' => $storeIds]) - ->groupBy('ex.entity_id'); + ->from(['w' => $type === 'writeOffs' ? 'write_offs' : 'sales']); + + if ($type === 'writeOffs') { + $query->leftJoin('export_import_table ex', 'ex.export_val = w.store_id') + ->join('JOIN', new Expression('LATERAL jsonb_array_elements(w.items::jsonb) AS item'), 'true'); + } else { + $query->leftJoin('sales_products sp', 'sp.check_id = w.id') + ->leftJoin('export_import_table ex', 'ex.export_val = w.store_id_1c'); + } + + $query->where(['>=', 'w.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]); if ($productFilter !== null) { - $query->andWhere(['sp.product_id' => $productFilter]); + if ($type === 'writeOffs') { + $query->andWhere(['item ->> \'product_id\'' => $productFilter]); + } else { + $query->andWhere(['sp.product_id' => $productFilter]); + } } - $rows = $query->all(); - $totals = []; - - foreach ($rows as $row) { - $totals[(int)$row['store_id']] = (float)$row['total_sum']; + if ($dateTo !== null) { + $query->andWhere(['<=', 'w.date', $dateTo]); } - return $totals; + $query->groupBy('ex.entity_id'); + + $rows = $query->all(); + + return ArrayHelper::map($rows, 'store_id', 'total_sum'); } - public function getMonthCategoryShare($dateFrom, $storeFilter = null, $productFilter = null): array + public function getMonthCategoryShareOrWriteOff(string $dateFrom, ?array $filters = null, ?array $productFilter = null, string $type = 'sales'): array { $stores = $this->getVisibleStores(); $storeIds = array_map(fn($s) => $s->id, $stores); - if ($storeFilter !== null) { - $storeIds = array_intersect($storeIds, (array)$storeFilter); + + if (!empty($filters) && array_key_exists('store_id', $filters) && $filters['store_id'] !== '') { + $storeIds = array_intersect($storeIds, [(int)$filters['store_id']]); } - $totals = $this->getStoreSalesTotals($storeIds, $dateFrom, $productFilter); + $totals = $this->getStoreTotals($storeIds, $dateFrom, null, $type); + if (empty($totals)) return []; $query = (new Query()) ->select([ 'store_id' => 'ex.entity_id', 'category' => 'p1c.category', - 'total_sum' => new Expression('SUM(sp.summ)') + 'total_sum' => new Expression( + $type === 'writeOffs' ? 'SUM(CAST(item ->> \'summ\' AS NUMERIC))' : 'SUM(sp.summ)' + ), ]) - ->from(['s' => 'sales']) - ->leftJoin('sales_products sp', 'sp.check_id = s.id') - ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = sp.product_id') - ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') - ->where(['>=', 's.date', $dateFrom]) - ->andWhere(['ex.entity_id' => $storeIds]) - ->andWhere(['<>', 'p1c.category', '']) - ->groupBy(['ex.entity_id', 'p1c.category']); - - if ($productFilter !== null) { - $query->andWhere(['sp.product_id' => $productFilter]); + ->from($type === 'writeOffs' ? ['w' => 'write_offs'] : ['s' => 'sales']); + + if ($type === 'writeOffs') { + $query->join('LEFT JOIN', 'export_import_table ex', 'ex.export_val = w.store_id') + ->join('JOIN', new Expression('LATERAL jsonb_array_elements(w.items::jsonb) AS item'), 'true') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = item ->> \'product_id\'') + ->where(['>=', 'w.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.category', '']) + ->groupBy(['ex.entity_id', 'p1c.category']); + + if ($productFilter !== null) { + $query->andWhere(['item ->> \'product_id\'' => $productFilter]); + } + } else { + $query->leftJoin('sales_products sp', 'sp.check_id = s.id') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = sp.product_id') + ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') + ->where(['>=', 's.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.category', '']) + ->groupBy(['ex.entity_id', 'p1c.category']); + + if ($productFilter !== null) { + $query->andWhere(['sp.product_id' => $productFilter]); + } } $rows = $query->all(); $result = []; + foreach ($rows as $row) { $storeId = $row['store_id']; $total = $totals[$storeId] ?? 1; @@ -93,7 +123,7 @@ class AutoPlannogrammaService return $result; } - public function getMonthCategoryGoal(array $categoryShare, $datePlan): array + public function getMonthCategoryGoal(array $categoryShare, $datePlan, $filters): array { $timestamp = strtotime($datePlan); $year = date('Y', $timestamp); @@ -114,7 +144,7 @@ class AutoPlannogrammaService $result[] = [ 'category' => $item['category'], 'store_id' => $storeId, - 'goal' => round($item['share_of_total'] * $plan['total_sales_plan'], 2), + 'goal' => round($item['share_of_total'] * ($filters['type'] == 'writeOffs' ? $plan['write_offs_plan'] : $plan['total_sales_plan']), 2), ]; } } @@ -122,56 +152,69 @@ class AutoPlannogrammaService return $result; } - public function getMonthSubcategoryShare($dateFrom, $datePlan, $storeFilter = null, $productFilter = null): array + public function getMonthSubcategoryShareOrWriteOff(string $dateFrom, ?array $filters = null, ?array $productFilter = null, string $type = 'sales'): array { - $month = (int)date('m', strtotime($datePlan)); - $stores = $this->getVisibleStores(); $storeIds = array_map(fn($s) => $s->id, $stores); - if ($storeFilter !== null) { - $storeIds = array_intersect($storeIds, (array)$storeFilter); + + if (!empty($filters) && array_key_exists('store_id', $filters) && $filters['store_id'] !== '') { + $storeIds = array_intersect($storeIds, [(int)$filters['store_id']]); } + $totals = $this->getStoreTotals($storeIds, $dateFrom, $productFilter, $type); + if (empty($totals)) return []; + $query = (new Query()) ->select([ 'store_id' => 'ex.entity_id', - 'category' => 'p1c.category', 'subcategory' => 'p1c.subcategory', - 'month' => new Expression('EXTRACT(MONTH FROM s.date)'), - 'total_sum' => new Expression('SUM(sp.summ)') - ]) - ->from(['sp' => 'sales_products']) - ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = sp.product_id') - ->leftJoin('sales s', 's.id = sp.check_id') - ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') - ->where(['>=', 's.date', $dateFrom]) - ->andWhere(['ex.entity_id' => $storeIds]) - ->groupBy(['ex.entity_id', 'p1c.category', 'p1c.subcategory', new Expression('EXTRACT(MONTH FROM s.date)')]); - - if ($productFilter !== null) { - $query->andWhere(['sp.product_id' => $productFilter]); + 'category' => 'p1c.category', + 'total_sum' => new Expression( + $type === 'writeOffs' ? 'SUM(CAST(item ->> \'summ\' AS NUMERIC))' : 'SUM(sp.summ)' + ), + ]); + + if ($type === 'writeOffs') { + $query->from(['w' => 'write_offs']) + ->join('LEFT JOIN', 'export_import_table ex', 'ex.export_val = w.store_id') + ->join('JOIN', new Expression('LATERAL jsonb_array_elements(w.items::jsonb) AS item'), 'true') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = item ->> \'product_id\'') + ->where(['>=', 'w.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.subcategory', '']) + ->groupBy(['ex.entity_id', 'p1c.subcategory', 'p1c.category']); + + if ($productFilter !== null) { + $query->andWhere(['item ->> \'product_id\'' => $productFilter]); + } + } else { + $query->from(['s' => 'sales']) + ->leftJoin('sales_products sp', 'sp.check_id = s.id') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = sp.product_id') + ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') + ->where(['>=', 's.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.subcategory', '']) + ->groupBy(['ex.entity_id', 'p1c.subcategory', 'p1c.category']); + + if ($productFilter !== null) { + $query->andWhere(['sp.product_id' => $productFilter]); + } } $rows = $query->all(); - $grouped = []; + $result = []; foreach ($rows as $row) { - if ((int)$row['month'] !== $month) continue; - $groupKey = "{$row['store_id']}_{$row['category']}_{$row['month']}"; - $grouped[$groupKey][] = $row; - } - - $result = []; - foreach ($grouped as $group) { - $total = array_sum(array_column($group, 'total_sum')) ?: 1; - foreach ($group as $item) { - $result[] = [ - 'store_id' => $item['store_id'], - 'category' => $item['category'], - 'subcategory' => $item['subcategory'], - 'percent_of_month' => round($item['total_sum'] / $total, 4), - ]; - } + $storeId = $row['store_id']; + $total = $totals[$storeId] ?? 1; + $result[] = [ + 'store_id' => $storeId, + 'category' => $row['category'], + 'subcategory' => $row['subcategory'], + 'total_sum' => $row['total_sum'], + 'percent_of_month' => round($row['total_sum'] / $total, 4), + ]; } return $result; @@ -200,65 +243,77 @@ class AutoPlannogrammaService return $result; } - public function getMonthSpeciesShare($dateFrom, $datePlan, $storeFilter = null, $productFilter = null): array + public function getMonthSpeciesShareOrWriteOff(string $dateFrom, ?array $filters = null, ?array $productFilter = null, string $type = 'sales'): array { - $month = (int)date('m', strtotime($datePlan)); - $stores = $this->getVisibleStores(); $storeIds = array_map(fn($s) => $s->id, $stores); - if ($storeFilter !== null) { - $storeIds = array_intersect($storeIds, (array)$storeFilter); + + if (!empty($filters) && array_key_exists('store_id', $filters) && $filters['store_id'] !== '') { + $storeIds = array_intersect($storeIds, [(int)$filters['store_id']]); } + $totals = $this->getStoreTotals($storeIds, $dateFrom, $productFilter, $type); + if (empty($totals)) return []; + $query = (new Query()) ->select([ 'store_id' => 'ex.entity_id', - 'category' => 'p1.category', - 'subcategory' => 'p1.subcategory', - 'species' => 'p1.name', - 'month' => new Expression('EXTRACT(MONTH FROM s.date)'), - 'total_sum' => new Expression('SUM(sp.summ)') - ]) - ->from(['sp' => 'sales_products']) - ->leftJoin('products_1c_nomenclature p1', 'p1.id = sp.product_id') - ->leftJoin('sales s', 's.id = sp.check_id') - ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') - ->where(['>=', 's.date', $dateFrom]) - ->andWhere(['ex.entity_id' => $storeIds]) - ->groupBy(['ex.entity_id', 'p1.category', 'p1.subcategory', 'p1.name', new Expression('EXTRACT(MONTH FROM s.date)')]); - - if ($productFilter !== null) { - $query->andWhere(['sp.product_id' => $productFilter]); + 'species' => 'p1c.species', + 'category' => 'p1c.category', + 'subcategory' => 'p1c.subcategory', + 'total_sum' => new Expression( + $type === 'writeOffs' ? 'SUM(CAST(item ->> \'summ\' AS NUMERIC))' : 'SUM(sp.summ)' + ), + ]); + + if ($type === 'writeOffs') { + $query->from(['w' => 'write_offs']) + ->join('LEFT JOIN', 'export_import_table ex', 'ex.export_val = w.store_id') + ->join('JOIN', new Expression('LATERAL jsonb_array_elements(w.items::jsonb) AS item'), 'true') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = item ->> \'product_id\'') + ->where(['>=', 'w.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.species', '']) + ->groupBy(['ex.entity_id', 'p1c.species', 'p1c.category', 'p1c.subcategory']); + + if ($productFilter !== null) { + $query->andWhere(['item ->> \'product_id\'' => $productFilter]); + } + } else { + $query->from(['s' => 'sales']) + ->leftJoin('sales_products sp', 'sp.check_id = s.id') + ->leftJoin('products_1c_nomenclature p1c', 'p1c.id = sp.product_id') + ->leftJoin('export_import_table ex', 'ex.export_val = s.store_id_1c') + ->where(['>=', 's.date', $dateFrom]) + ->andWhere(['ex.entity_id' => $storeIds]) + ->andWhere(['<>', 'p1c.species', '']) + ->groupBy(['ex.entity_id', 'p1c.species', 'p1c.category', 'p1c.subcategory']); + + if ($productFilter !== null) { + $query->andWhere(['sp.product_id' => $productFilter]); + } } $rows = $query->all(); - $grouped = []; + $result = []; foreach ($rows as $row) { - if ((int)$row['month'] !== $month) continue; - $key = "{$row['store_id']}_{$row['category']}_{$row['subcategory']}"; - $grouped[$key][] = $row; - } - - $result = []; - foreach ($grouped as $group) { - $total = array_sum(array_column($group, 'total_sum')) ?: 1; - foreach ($group as $item) { - $result[] = [ - 'store_id' => $item['store_id'], - 'category' => $item['category'], - 'subcategory' => $item['subcategory'], - 'species' => $item['species'], - 'percent_of_month' => round($item['total_sum'] / $total, 6), - 'goal' => null, - ]; - } + $storeId = $row['store_id']; + $total = $totals[$storeId] ?? 1; + $result[] = [ + 'store_id' => $storeId, + 'category' => $row['category'], + 'subcategory' => $row['subcategory'], + 'species' => $row['species'], + 'total_sum' => $row['total_sum'], + 'percent_of_month' => round($row['total_sum'] / $total, 4), + ]; } return $result; } - public function getMonthSpeciesGoalDirtry(array $speciesShare, array $subcategoryGoals): array + public function getMonthSpeciesGoalDirty(array $speciesShare, array $subcategoryGoals): array { $indexedGoals = []; foreach ($subcategoryGoals as $goal) { @@ -281,4 +336,45 @@ class AutoPlannogrammaService return $result; } + + public function calculateFullGoalChain(array $filters): array + { + $datePlan = $filters['plan_date']; + $dateFromForCategory = (new \DateTime($datePlan))->modify('-12 months')->format('Y-m-d'); + $dateFrom = (new \DateTime($datePlan))->modify('-3 months')->format('Y-m-d'); + + $monthCategoryShare = $this->getMonthCategoryShareOrWriteOff($dateFromForCategory, $filters); + $monthCategoryGoal = $this->getMonthCategoryGoal($monthCategoryShare, $datePlan, $filters); + + $monthSubcategoryShare = $this->getMonthSubcategoryShareOrWriteOff($dateFrom, $filters); + $monthSubcategoryGoal = $this->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); + + $monthSpeciesShare = $this->getMonthSpeciesShareOrWriteOff($dateFrom, $filters); + $monthSpeciesGoal = $this->getMonthSpeciesGoalDirty($monthSpeciesShare, $monthSubcategoryGoal); + + $filtered = array_filter($monthSpeciesGoal, function ($row) use ($filters) { + foreach ($filters as $key => $value) { + if ($value === null || $value === '') { + continue; + } + + if (!array_key_exists($key, $row)) { + continue; + } + + if (is_numeric($row[$key]) && is_numeric($value)) { + if ((float)$row[$key] !== (float)$value) { + return false; + } + } else { + if (stripos((string)$row[$key], (string)$value) === false) { + return false; + } + } + } + return true; + }); + + return array_values($filtered); + } } diff --git a/erp24/views/auto-planogramma/test-sales.php b/erp24/views/auto-planogramma/calculating.php similarity index 100% rename from erp24/views/auto-planogramma/test-sales.php rename to erp24/views/auto-planogramma/calculating.php diff --git a/erp24/views/auto-planogramma/sales.php b/erp24/views/auto-planogramma/control.php similarity index 100% rename from erp24/views/auto-planogramma/sales.php rename to erp24/views/auto-planogramma/control.php -- 2.39.5