]);
}
- public function actionTestSales()
+ public function actionCalculating()
{
$request = Yii::$app->request;
]);
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'];
}
}
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
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
use yii\db\Expression;
use yii\db\Query;
+use yii\helpers\ArrayHelper;
use yii_app\records\CityStore;
use yii_app\records\SalesWriteOffsPlan;
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;
return $result;
}
- public function getMonthCategoryGoal(array $categoryShare, $datePlan): array
+ public function getMonthCategoryGoal(array $categoryShare, $datePlan, $filters): array
{
$timestamp = strtotime($datePlan);
$year = date('Y', $timestamp);
$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),
];
}
}
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;
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) {
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);
+ }
}
--- /dev/null
+<?php
+
+use kartik\date\DatePicker;
+use kartik\select2\Select2;
+use yii\helpers\ArrayHelper;
+use yii\helpers\Html;
+use yii\widgets\ActiveForm;
+use yii\grid\GridView;
+use yii_app\records\CityStore;
+use yii_app\records\Products1cNomenclature;
+
+/** @var array $filters */
+?>
+
+<div class="filter-form" style="margin-bottom: 20px;">
+ <?php $form = ActiveForm::begin(['method' => 'get']); ?>
+ <div class="row p-3">
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['category' => $filters['category'] ?? '']), 'category')->widget(Select2::class, [
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('category')->distinct()->asArray()->all(),
+ 'category',
+ 'category'
+ ),
+ 'options' => ['placeholder' => 'Категория', 'name' => 'category'],
+ 'pluginOptions' => ['allowClear' => true],
+ ])->label('Категория') ?>
+ </div>
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['subcategory' => $filters['subcategory'] ?? '']), 'subcategory')->widget(Select2::class, [
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('subcategory')->distinct()->asArray()->all(),
+ 'subcategory',
+ 'subcategory'
+ ),
+ 'options' => ['placeholder' => 'Подкатегория', 'name' => 'subcategory'],
+ 'pluginOptions' => ['allowClear' => true],
+ ])->label('Подкатегория') ?>
+ </div>
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['product_name' => $filters['product_name'] ?? '']), 'product_name')->widget(Select2::class, [
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('name')->distinct()->asArray()->all(),
+ 'name',
+ 'name'
+ ),
+ 'options' => ['placeholder' => 'Название товара', 'name' => 'product_name'],
+ 'pluginOptions' => ['allowClear' => true],
+ ])->label('Товар') ?>
+ </div>
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['store_id' => $filters['store_id'] ?? '']), 'store_id')->widget(Select2::class, [
+ 'data' => ArrayHelper::map(
+ CityStore::findAll(['visible' => CityStore::IS_VISIBLE]),
+ 'id',
+ 'name'
+ ),
+ 'options' => ['placeholder' => 'Магазин', 'name' => 'store_id'],
+ 'pluginOptions' => ['allowClear' => true],
+ ])->label('Магазин') ?>
+ </div>
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['plan_date' => $filters['plan_date'] ?? '']), 'plan_date')->widget(DatePicker::class, [
+ 'pluginOptions' => [
+ 'autoclose' => true,
+ 'format' => 'dd-mm-yyyy',
+ ],
+ 'options' => [
+ 'class' => 'form-control',
+ 'placeholder' => 'Плановая дата',
+ 'name' => 'plan_date',
+ ],
+ ])->label('Плановая дата') ?>
+ </div>
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
+ 'data' => [
+ 'writeOffs' => 'Списания',
+ 'sales' => 'Продажи'
+ ],
+ 'options' => ['placeholder' => 'Тип', 'name' => 'type'],
+ 'pluginOptions' => ['allowClear' => true],
+ ])->label('По дефолту продажи!') ?>
+ </div>
+ <div class="col-md">
+ <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
+ </div>
+ <div class="col-md">
+ <?= Html::a('Сбросить', ['auto-planogramma/test-sales'], ['class' => 'btn btn-default']) ?>
+ </div>
+ </div>
+
+ <?php ActiveForm::end(); ?>
+</div>
+
+<?= GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ 'category',
+ 'subcategory',
+ 'product_name',
+ 'store_id',
+ [
+ 'attribute' => 'goal',
+ 'label' => 'План закупок (RUB)',
+ ],
+ ],
+]); ?>
--- /dev/null
+<div class="filter-form" style="margin-bottom: 20px;">
+ <?php use kartik\date\DatePicker;
+ use kartik\select2\Select2;
+ use yii\grid\GridView;
+ use yii\helpers\ArrayHelper;
+ use yii\helpers\Html;
+ use yii\widgets\ActiveForm;
+ use yii_app\records\CityStore;
+ use yii_app\records\Products1cNomenclature;
+
+ $form = ActiveForm::begin(['method' => 'get']); ?>
+ <div class="row">
+ <div class="col-md">
+ <?= Select2::widget([
+ 'name' => 'category',
+ 'value' => $filters['category'] ?? '',
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('category')->distinct()->orderBy('category')->asArray()->all(),
+ 'category',
+ 'category'
+ ),
+ 'options' => ['placeholder' => 'Категория'],
+ 'pluginOptions' => ['allowClear' => true],
+ ]) ?>
+ </div>
+
+ <div class="col-md">
+ <?= Select2::widget([
+ 'name' => 'subcategory',
+ 'value' => $filters['subcategory'] ?? '',
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('subcategory')->distinct()->orderBy('subcategory')->asArray()->all(),
+ 'subcategory',
+ 'subcategory'
+ ),
+ 'options' => ['placeholder' => 'Подкатегория'],
+ 'pluginOptions' => ['allowClear' => true],
+ ]) ?>
+ </div>
+ <div class="col-md">
+ <?= Select2::widget([
+ 'name' => 'product_name',
+ 'value' => $filters['product_name'] ?? '',
+ 'data' => ArrayHelper::map(
+ Products1cNomenclature::find()->select('name')->distinct()->orderBy('name')->asArray()->all(),
+ 'name',
+ 'name'
+ ),
+ 'options' => ['placeholder' => 'Товар'],
+ 'pluginOptions' => ['allowClear' => true],
+ ]) ?>
+ </div>
+
+
+ <div class="col-md">
+ <?= Select2::widget([
+ 'name' => 'city_name',
+ 'value' => $filters['city_name'] ?? '',
+ 'data' => ArrayHelper::map(
+ CityStore::find()->select(['name'])->distinct()->orderBy('name')->asArray()->all(),
+ 'name',
+ 'name'
+ ),
+ 'options' => ['placeholder' => 'Магазин'],
+ 'pluginOptions' => ['allowClear' => true],
+ ]) ?>
+ </div>
+
+ <div class="col-md">
+ <?= DatePicker::widget([
+ 'name' => 'plan_date',
+ 'value' => $filters['plan_date'] ?? '',
+ 'pluginOptions' => [
+ 'autoclose' => true,
+ 'format' => 'dd-mm-yyyy',
+ ],
+ 'options' => [
+ 'class' => 'form-control',
+ 'placeholder' => 'Плановая дата',
+ ],
+ ]) ?>
+ </div>
+
+ <div class="col-md">
+ <?= Select2::widget([
+ 'name' => 'type',
+ 'value' => $filters['type'] ?? '',
+ 'data' => [
+ 'writeOffs' => 'Списания',
+ 'sales' => 'Продажи'
+ ],
+ 'options' => ['placeholder' => 'Тип'],
+ 'pluginOptions' => ['allowClear' => true],
+ ]) ?>
+ </div>
+
+
+ <div class="col-md">
+ <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
+ </div>
+ <div class="col-md">
+ <?= Html::a('Сбросить', ['auto-planogramma/sales'], ['class' => 'btn btn-default']) ?>
+ </div>
+ </div>
+ <?php ActiveForm::end(); ?>
+</div>
+
+<?= GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ 'category',
+ 'subcategory',
+ ['attribute' => 'product_name', 'label' => 'Товар'],
+ ['attribute' => 'city_name', 'label' => 'Магазин'],
+ ['attribute' => 'count', 'label' => 'Кол-во'],
+ ['attribute' => 'sum', 'label' => 'Сумма'],
+ ],
+]) ?>
+++ /dev/null
-<div class="filter-form" style="margin-bottom: 20px;">
- <?php use kartik\date\DatePicker;
- use kartik\select2\Select2;
- use yii\grid\GridView;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Html;
- use yii\widgets\ActiveForm;
- use yii_app\records\CityStore;
- use yii_app\records\Products1cNomenclature;
-
- $form = ActiveForm::begin(['method' => 'get']); ?>
- <div class="row">
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'category',
- 'value' => $filters['category'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('category')->distinct()->orderBy('category')->asArray()->all(),
- 'category',
- 'category'
- ),
- 'options' => ['placeholder' => 'Категория'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'subcategory',
- 'value' => $filters['subcategory'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('subcategory')->distinct()->orderBy('subcategory')->asArray()->all(),
- 'subcategory',
- 'subcategory'
- ),
- 'options' => ['placeholder' => 'Подкатегория'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'product_name',
- 'value' => $filters['product_name'] ?? '',
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('name')->distinct()->orderBy('name')->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Товар'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'city_name',
- 'value' => $filters['city_name'] ?? '',
- 'data' => ArrayHelper::map(
- CityStore::find()->select(['name'])->distinct()->orderBy('name')->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Магазин'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= DatePicker::widget([
- 'name' => 'plan_date',
- 'value' => $filters['plan_date'] ?? '',
- 'pluginOptions' => [
- 'autoclose' => true,
- 'format' => 'dd-mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- ],
- ]) ?>
- </div>
-
- <div class="col-md">
- <?= Select2::widget([
- 'name' => 'type',
- 'value' => $filters['type'] ?? '',
- 'data' => [
- 'writeOffs' => 'Списания',
- 'sales' => 'Продажи'
- ],
- 'options' => ['placeholder' => 'Тип'],
- 'pluginOptions' => ['allowClear' => true],
- ]) ?>
- </div>
-
-
- <div class="col-md">
- <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
- </div>
- <div class="col-md">
- <?= Html::a('Сбросить', ['auto-planogramma/sales'], ['class' => 'btn btn-default']) ?>
- </div>
- </div>
- <?php ActiveForm::end(); ?>
-</div>
-
-<?= GridView::widget([
- 'dataProvider' => $dataProvider,
- 'columns' => [
- 'category',
- 'subcategory',
- ['attribute' => 'product_name', 'label' => 'Товар'],
- ['attribute' => 'city_name', 'label' => 'Магазин'],
- ['attribute' => 'count', 'label' => 'Кол-во'],
- ['attribute' => 'sum', 'label' => 'Сумма'],
- ],
-]) ?>
+++ /dev/null
-<?php
-
-use kartik\date\DatePicker;
-use kartik\select2\Select2;
-use yii\helpers\ArrayHelper;
-use yii\helpers\Html;
-use yii\widgets\ActiveForm;
-use yii\grid\GridView;
-use yii_app\records\CityStore;
-use yii_app\records\Products1cNomenclature;
-
-/** @var array $filters */
-?>
-
-<div class="filter-form" style="margin-bottom: 20px;">
- <?php $form = ActiveForm::begin(['method' => 'get']); ?>
- <div class="row p-3">
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['category' => $filters['category'] ?? '']), 'category')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('category')->distinct()->asArray()->all(),
- 'category',
- 'category'
- ),
- 'options' => ['placeholder' => 'Категория', 'name' => 'category'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Категория') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['subcategory' => $filters['subcategory'] ?? '']), 'subcategory')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('subcategory')->distinct()->asArray()->all(),
- 'subcategory',
- 'subcategory'
- ),
- 'options' => ['placeholder' => 'Подкатегория', 'name' => 'subcategory'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Подкатегория') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['product_name' => $filters['product_name'] ?? '']), 'product_name')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- Products1cNomenclature::find()->select('name')->distinct()->asArray()->all(),
- 'name',
- 'name'
- ),
- 'options' => ['placeholder' => 'Название товара', 'name' => 'product_name'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Товар') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['store_id' => $filters['store_id'] ?? '']), 'store_id')->widget(Select2::class, [
- 'data' => ArrayHelper::map(
- CityStore::findAll(['visible' => CityStore::IS_VISIBLE]),
- 'id',
- 'name'
- ),
- 'options' => ['placeholder' => 'Магазин', 'name' => 'store_id'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('Магазин') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['plan_date' => $filters['plan_date'] ?? '']), 'plan_date')->widget(DatePicker::class, [
- 'pluginOptions' => [
- 'autoclose' => true,
- 'format' => 'dd-mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
- </div>
- <div class="col-md">
- <?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
- 'data' => [
- 'writeOffs' => 'Списания',
- 'sales' => 'Продажи'
- ],
- 'options' => ['placeholder' => 'Тип', 'name' => 'type'],
- 'pluginOptions' => ['allowClear' => true],
- ])->label('По дефолту продажи!') ?>
- </div>
- <div class="col-md">
- <?= Html::submitButton('Фильтровать', ['class' => 'btn btn-primary']) ?>
- </div>
- <div class="col-md">
- <?= Html::a('Сбросить', ['auto-planogramma/test-sales'], ['class' => 'btn btn-default']) ?>
- </div>
- </div>
-
- <?php ActiveForm::end(); ?>
-</div>
-
-<?= GridView::widget([
- 'dataProvider' => $dataProvider,
- 'columns' => [
- 'category',
- 'subcategory',
- 'product_name',
- 'store_id',
- [
- 'attribute' => 'goal',
- 'label' => 'План закупок (RUB)',
- ],
- ],
-]); ?>