From: fomichev Date: Fri, 27 Jun 2025 08:14:48 +0000 (+0300) Subject: Разделение продаж на типы для подкатегорий и видов X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=13e4ffd7d809eae6a544a0c3773f5b2cbd05ae33;p=erp24_rep%2Fyii-erp24%2F.git Разделение продаж на типы для подкатегорий и видов --- diff --git a/erp24/controllers/AutoPlannogrammaController.php b/erp24/controllers/AutoPlannogrammaController.php index 72787a0d..f6c78ad3 100644 --- a/erp24/controllers/AutoPlannogrammaController.php +++ b/erp24/controllers/AutoPlannogrammaController.php @@ -480,6 +480,7 @@ class AutoPlannogrammaController extends BaseController 'year' => $request->get('year'), 'month' => $request->get('month'), 'type' => $request->get('type'), + 'sales_type' => $request->get('sales_type'), ]; $dataProvider = new ArrayDataProvider([ @@ -493,7 +494,7 @@ class AutoPlannogrammaController extends BaseController $service = new AutoPlannogrammaService(); $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']); - $data = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date'], $filters['type']); + $data = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date'], $filters['type'], $filters['sales_type']); $flatData = array_filter($data, function ($row) use ($filters) { foreach ($filters as $key => $value) { @@ -530,6 +531,7 @@ class AutoPlannogrammaController extends BaseController 'year' => $request->get('year'), 'month' => $request->get('month'), 'type' => $request->get('type'), + 'sales_type' => $request->get('sales_type'), ]; $dataProvider = new ArrayDataProvider([ @@ -581,6 +583,7 @@ class AutoPlannogrammaController extends BaseController 'year' => $request->get('year'), 'month' => $request->get('month'), 'type' => $request->get('type'), + 'sales_type' => $request->get('sales_type'), ]; $dataProvider = new ArrayDataProvider([ @@ -594,7 +597,7 @@ class AutoPlannogrammaController extends BaseController $service = new AutoPlannogrammaService(); $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters); - $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date']); + $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date'], $filters['type'], $filters['sales_type']); $monthSubcategoryShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters); $data = $service->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); @@ -640,6 +643,7 @@ class AutoPlannogrammaController extends BaseController 'year' => $request->get('year'), 'month' => $request->get('month'), 'type' => $request->get('type'), + 'sales_type' => $request->get('sales_type'), ]; $dataProvider = new ArrayDataProvider([ @@ -690,6 +694,7 @@ class AutoPlannogrammaController extends BaseController 'year' => $request->get('year'), 'month' => $request->get('month'), 'type' => $request->get('type'), + 'sales_type' => $request->get('sales_type'), ]; $dataProvider = new ArrayDataProvider([ @@ -704,7 +709,7 @@ class AutoPlannogrammaController extends BaseController $service = new AutoPlannogrammaService(); $monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters); - $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date']); + $monthCategoryGoal = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date'], $filters['type'], $filters['sales_type']); $monthSubcategoryShare = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters); $monthSubcategoryGoal = $service->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal); $monthSpeciesShare = $service->getMonthSpeciesShareOrWriteOff($filters['plan_date'], $filters); diff --git a/erp24/services/AutoPlannogrammaService.php b/erp24/services/AutoPlannogrammaService.php index a83dc2cd..0f56cfb3 100644 --- a/erp24/services/AutoPlannogrammaService.php +++ b/erp24/services/AutoPlannogrammaService.php @@ -269,7 +269,7 @@ class AutoPlannogrammaService * @param array $filters Фильтры * @return array Массив с целями по категориям */ - public function getMonthCategoryGoal(array $categoryShare, string $datePlan, string $type = self::TYPE_SALES): array + public function getMonthCategoryGoal(array $categoryShare, string $datePlan, string $type = self::TYPE_SALES, string $sales_type = null): array { $timestamp = strtotime($datePlan); $year = date('Y', $timestamp); @@ -288,12 +288,17 @@ class AutoPlannogrammaService if (!isset($categoryShare[$storeId])) { continue; } + $goal = match ($sales_type) { + 'offline' => $plan['offline_sales_plan'], + 'online' => (int)$plan['online_sales_shop_plan'] + (int)$plan['online_sales_marketplace_plan'], + default => ($type === self::TYPE_WRITE_OFFS ? $plan['write_offs_plan'] : $plan['total_sales_plan']), + }; foreach ($categoryShare[$storeId] as $item) { $result[] = [ 'category' => $item['category'], 'store_id' => $storeId, - 'goal' => round($item['percent'] * ($type === self::TYPE_WRITE_OFFS ? $plan['write_offs_plan'] : $plan['total_sales_plan']), 2), + 'goal' => round($item['percent'] * $goal, 2), ]; } } @@ -315,6 +320,18 @@ class AutoPlannogrammaService $storeIds = array_intersect($storeIds, [(int)$filters['store_id']]); } + $mode = null; + + if (!empty($filters['sales_type'])) { + $mode = $filters['sales_type']; + } + $orderCondition = []; + if ($mode === 'offline') { + $orderCondition = ['order_id' => ['', '0']]; + } elseif ($mode === 'online') { + $orderCondition = ['not in', 'order_id', ['', '0']]; + } + $sumExpression = $type === self::TYPE_WRITE_OFFS ? 'SUM(wp.summ)' : "SUM(CASE @@ -370,6 +387,7 @@ class AutoPlannogrammaService ->leftJoin('export_import_table ex', $storeJoinCondition) ->leftJoin('products_1c p1', "p1.id = $productJoinCondition") ->andWhere(['ex.entity_id' => $storeIds]) + ->andFilterWhere($orderCondition) ->andWhere(['p1.components' => '']) ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']]) ->andWhere(['or', ...$months]) @@ -388,6 +406,7 @@ class AutoPlannogrammaService ->leftJoin('export_import_table ex', $storeJoinCondition) ->leftJoin('products_1c p1', "p1.id = $productJoinCondition") ->andWhere(['ex.entity_id' => $storeIds]) + ->andFilterWhere($orderCondition) ->andWhere(['p1.components' => '']) ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']]) ->andWhere(['or', ...$months]) @@ -403,7 +422,7 @@ class AutoPlannogrammaService ]; $componentAdds = []; $componentAddsSumAll = []; - $allComponentsProdIds = []; + $allComponentsProductIds = []; foreach ($storeIds as $sid) { foreach ($periods as $dt) { @@ -417,13 +436,20 @@ class AutoPlannogrammaService continue; } - foreach ($items as $it) { - $allComponentsProdIds[$sid][] = $it['product_id']; - } + $filtered = match ($mode) { + 'offline' => array_filter($items, fn($it) => in_array($it['order_id'], ['', '0'], true)), + 'online' => array_filter($items, fn($it) => !in_array($it['order_id'], ['', '0'], true)), + default => $items, // для writeOffs — всё + }; + + $allComponentsProductIds[$sid] = array_merge( + $allComponentsProductIds[$sid] ?? [], + array_column($filtered, 'product_id') + ); + $sums = $this->sumProductsComponentsByGroup($filtered, $type, 'subcategory'); - $sums = $this->sumProductsComponentsByGroup($items, $type, 'subcategory'); - $allComponentsProdIds[$sid] = array_unique($allComponentsProdIds[$sid]); + $allComponentsProductIds[$sid] = array_values(array_unique($allComponentsProductIds[$sid])); foreach ($sums as $sr) { $cat = $sr['category']; @@ -472,7 +498,8 @@ class AutoPlannogrammaService 'type' => $type, 'new_total_store' => $newCatTotal, 'base_total_store' => $catTotal, - 'products_components_list' => implode(',', $allComponentsProdIds[$sid] ?? []), + 'products_components_list' => implode(',', $allComponentsProductIds[$sid] ?? []), + 'mode' => $mode ]; } @@ -539,6 +566,18 @@ class AutoPlannogrammaService $storeIds = array_intersect($storeIds, [(int)$filters['store_id']]); } + $mode = null; + + if (!empty($filters['sales_type'])) { + $mode = $filters['sales_type']; + } + $orderCondition = []; + if ($mode === 'offline') { + $orderCondition = ['order_id' => ['', '0']]; + } elseif ($mode === 'online') { + $orderCondition = ['not in', 'order_id', ['', '0']]; + } + $sumExpression = $type === self::TYPE_WRITE_OFFS ? 'SUM(wp.summ)' : "SUM(CASE @@ -595,6 +634,7 @@ class AutoPlannogrammaService ->leftJoin('export_import_table ex', $storeJoinCondition) ->leftJoin('products_1c p1', "p1.id = $productJoinCondition") ->andWhere(['ex.entity_id' => $storeIds]) + ->andFilterWhere($orderCondition) ->andWhere(['p1.components' => '']) ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']]) ->andWhere(['or', ...$months]) @@ -614,6 +654,7 @@ class AutoPlannogrammaService ->leftJoin('export_import_table ex', $storeJoinCondition) ->leftJoin('products_1c p1', "p1.id = $productJoinCondition") ->andWhere(['ex.entity_id' => $storeIds]) + ->andFilterWhere($orderCondition) ->andWhere(['p1.components' => '']) ->andWhere(['not in', 'p1c.category', ['', 'букет', 'сборка', 'сервис']]) ->andWhere(['or', ...$months]) @@ -663,7 +704,7 @@ class AutoPlannogrammaService $finalResult = []; $componentAdds = []; $componentAddsSumAll = []; - $allComponentsProdIds = []; + $allComponentsProductIds = []; foreach ($storeIds as $sid) { foreach ($periods as $dt) { @@ -677,13 +718,20 @@ class AutoPlannogrammaService continue; } - foreach ($items as $it) { - $allComponentsProdIds[$sid][] = $it['product_id']; - } + $filtered = match ($mode) { + 'offline' => array_filter($items, fn($it) => in_array($it['order_id'], ['', '0'], true)), + 'online' => array_filter($items, fn($it) => !in_array($it['order_id'], ['', '0'], true)), + default => $items, // для writeOffs — всё + }; + + $allComponentsProductIds[$sid] = array_merge( + $allComponentsProductIds[$sid] ?? [], + array_column($filtered, 'product_id') + ); + $sums = $this->sumProductsComponentsByGroup($filtered, $type, 'species'); - $sums = $this->sumProductsComponentsByGroup($items, $type, 'species'); - $allComponentsProdIds[$sid] = array_unique($allComponentsProdIds[$sid]); + $allComponentsProductIds[$sid] = array_values(array_unique($allComponentsProductIds[$sid])); foreach ($sums as $sr) { $cat = $sr['category']; @@ -734,7 +782,8 @@ class AutoPlannogrammaService 'type' => $type, 'new_total_store' => $newSubcatTotal, 'base_total_store' => $subcatTotal, - 'products_components_list' => implode(',', $allComponentsProdIds[$sid] ?? []), + 'products_components_list' => implode(',', $allComponentsProductIds[$sid] ?? []), + 'mode' => $mode ]; } diff --git a/erp24/views/auto-plannogramma/2.php b/erp24/views/auto-plannogramma/2.php index d6c71186..2a756803 100644 --- a/erp24/views/auto-plannogramma/2.php +++ b/erp24/views/auto-plannogramma/2.php @@ -58,6 +58,16 @@ 'pluginOptions' => ['allowClear' => true], ])->label('По дефолту продажи!') ?> +
+ field(new \yii\base\DynamicModel(['sales_type' => $filters['sales_type'] ?? '']), 'sales_type')->widget(Select2::class, [ + 'data' => [ + 'offline' => 'оффлайн', + 'online' => 'онлайн' + ], + 'options' => ['placeholder' => 'Тип продаж', 'name' => 'sales_type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Только для типа Продажи!') ?> +
'btn btn-primary']) ?>
@@ -71,11 +81,12 @@ $dataProvider, + 'showPageSummary' => true, 'columns' => [ ['attribute' => 'store_id', 'label' => 'Магазин', 'value' => function ($data) { return CityStore::findOne($data['store_id'])->name ?? null; }], ['attribute' => 'category', 'label' => 'Категория'], - ['attribute' => 'goal', 'label' => 'Сумма план'], + ['attribute' => 'goal', 'label' => 'Сумма план','pageSummary' => true,], ], ]); ?> diff --git a/erp24/views/auto-plannogramma/3.php b/erp24/views/auto-plannogramma/3.php index c3fa44f4..e602eec0 100644 --- a/erp24/views/auto-plannogramma/3.php +++ b/erp24/views/auto-plannogramma/3.php @@ -68,6 +68,16 @@ 'pluginOptions' => ['allowClear' => true], ])->label('По дефолту продажи!') ?> +
+ field(new \yii\base\DynamicModel(['sales_type' => $filters['sales_type'] ?? '']), 'sales_type')->widget(Select2::class, [ + 'data' => [ + 'offline' => 'оффлайн', + 'online' => 'онлайн' + ], + 'options' => ['placeholder' => 'Тип продаж', 'name' => 'sales_type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Только для типа Продажи!') ?> +
'btn btn-primary']) ?>
@@ -90,6 +100,6 @@ ['attribute' => 'subcategory', 'label' => 'Подкатегория'], ['attribute' => 'old_total_sum', 'label' => 'Сумма', 'format' => ['decimal', 2], 'pageSummary' => true,], ['attribute' => 'total_sum', 'label' => 'Сумма с раскрытием', 'format' => ['decimal', 2], 'pageSummary' => true,], - ['attribute' => 'percent', 'label' => 'Доля', 'format' => ['percent', 2]], + ['attribute' => 'percent', 'label' => 'Доля', 'format' => ['percent', 2], 'pageSummary' => true,], ], ]); ?> diff --git a/erp24/views/auto-plannogramma/4.php b/erp24/views/auto-plannogramma/4.php index a5d0d6e4..903903b4 100644 --- a/erp24/views/auto-plannogramma/4.php +++ b/erp24/views/auto-plannogramma/4.php @@ -70,6 +70,16 @@ 'pluginOptions' => ['allowClear' => true], ])->label('По дефолту продажи!') ?> +
+ field(new \yii\base\DynamicModel(['sales_type' => $filters['sales_type'] ?? '']), 'sales_type')->widget(Select2::class, [ + 'data' => [ + 'offline' => 'оффлайн', + 'online' => 'онлайн' + ], + 'options' => ['placeholder' => 'Тип продаж', 'name' => 'sales_type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Только для типа Продажи!') ?> +
'btn btn-primary']) ?>
diff --git a/erp24/views/auto-plannogramma/5.php b/erp24/views/auto-plannogramma/5.php index 6903b9b1..0771f77b 100644 --- a/erp24/views/auto-plannogramma/5.php +++ b/erp24/views/auto-plannogramma/5.php @@ -81,6 +81,16 @@ 'pluginOptions' => ['allowClear' => true], ])->label('По дефолту продажи!') ?> +
+ field(new \yii\base\DynamicModel(['sales_type' => $filters['sales_type'] ?? '']), 'sales_type')->widget(Select2::class, [ + 'data' => [ + 'offline' => 'оффлайн', + 'online' => 'онлайн' + ], + 'options' => ['placeholder' => 'Тип продаж', 'name' => 'sales_type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Только для типа Продажи!') ?> +
'btn btn-primary']) ?>
diff --git a/erp24/views/auto-plannogramma/6.php b/erp24/views/auto-plannogramma/6.php index b3513621..d4ace885 100644 --- a/erp24/views/auto-plannogramma/6.php +++ b/erp24/views/auto-plannogramma/6.php @@ -81,6 +81,16 @@ 'pluginOptions' => ['allowClear' => true], ])->label('По дефолту продажи!') ?> +
+ field(new \yii\base\DynamicModel(['sales_type' => $filters['sales_type'] ?? '']), 'sales_type')->widget(Select2::class, [ + 'data' => [ + 'offline' => 'оффлайн', + 'online' => 'онлайн' + ], + 'options' => ['placeholder' => 'Тип продаж', 'name' => 'sales_type'], + 'pluginOptions' => ['allowClear' => true], + ])->label('Только для типа Продажи!') ?> +
'btn btn-primary']) ?>