$filters = [
'category' => $request->get('category'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
'allModels' => [],
'pagination' => ['pageSize' => 100],
]);
- if (!empty($filters['plan_date'])) {
- $planDateParts = explode('-', $filters['plan_date']);
- if (count($planDateParts) === 2) {
- [$month, $year] = $planDateParts;
- $filters['plan_date'] = "$year-$month-01";
- }
+
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
$service = new AutoPlannogrammaService();
$data = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']);
$filters = [
'category' => $request->get('category'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
'pagination' => ['pageSize' => 100],
]);
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
- if (!empty($filters['plan_date'])) {
- $planDateParts = explode('-', $filters['plan_date']);
- if (count($planDateParts) === 2) {
- [$month, $year] = $planDateParts;
- $filters['plan_date'] = "$year-$month-01";
- }
$service = new AutoPlannogrammaService();
$monthCategoryShare = $service->getMonthCategoryShareOrWriteOff($filters['plan_date'], $filters);
$data = $service->getMonthCategoryGoal($monthCategoryShare, $filters['plan_date'], $filters);
-
$flatData = array_filter($data, function ($row) use ($filters) {
foreach ($filters as $key => $value) {
if (empty($value)) continue;
return true;
});
-
$dataProvider = new ArrayDataProvider([
'allModels' => $flatData,
'pagination' => ['pageSize' => 100],
]);
}
+
return $this->render('2', [
'dataProvider' => $dataProvider,
'filters' => $filters,
'category' => $request->get('category'),
'subcategory' => $request->get('subcategory'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
]);
- if (!empty($filters['plan_date'])) {
- $planDateParts = explode('-', $filters['plan_date']);
- if (count($planDateParts) === 2) {
- [$month, $year] = $planDateParts;
- $filters['plan_date'] = "$year-$month-01";
- }
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
$service = new AutoPlannogrammaService();
$data = $service->getMonthSubcategoryShareOrWriteOff($filters['plan_date'], $filters, $filters['type']);
'category' => $request->get('category'),
'subcategory' => $request->get('subcategory'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
]);
- if (!empty($filters['plan_date'])) {
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
$planDateParts = explode('-', $filters['plan_date']);
if (count($planDateParts) === 2) {
[$month, $year] = $planDateParts;
'subcategory' => $request->get('subcategory'),
'species' => $request->get('species'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
'pagination' => ['pageSize' => 100],
]);
-
- if (!empty($filters['plan_date'])) { $planDateParts = explode('-', $filters['plan_date']);
- if (count($planDateParts) === 2) {
- [$month, $year] = $planDateParts;
- $filters['plan_date'] = "$year-$month-01";
- }
-
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
$service = new AutoPlannogrammaService();
$data = $service->getMonthSpeciesShareOrWriteOff(
'subcategory' => $request->get('subcategory'),
'species' => $request->get('species'),
'store_id' => $request->get('store_id'),
- 'plan_date' => $request->get('plan_date'),
+ 'year' => $request->get('year'),
+ 'month' => $request->get('month'),
'type' => $request->get('type'),
];
]);
- if (!empty($filters['plan_date'])) {
- $planDateParts = explode('-', $filters['plan_date']);
- if (count($planDateParts) === 2) {
- [$month, $year] = $planDateParts;
- $filters['plan_date'] = "$year-$month-01";
- }
-
+ // Обработка даты на год и месяц
+ if (!empty($filters['year']) && !empty($filters['month'])) {
+ $filters['plan_date'] = $filters['year'] . '-' . str_pad($filters['month'], 2, '0', STR_PAD_LEFT) . '-01';
$service = new AutoPlannogrammaService();
$monthCategoryShare = $service->getMonthCategoryShareOrWriteOff(
return [];
}
- if (!in_array($type, [self::TYPE_SALES, self::TYPE_WRITE_OFFS], true)) {
- throw new \InvalidArgumentException("Недопустимый тип операции: $type");
- }
-
$query = $this->buildBaseTotalsQuery($type);
$query = $this->applyJoins($query, $type);
*/
public function getMonthCategoryShareOrWriteOff(string $dateFrom, ?array $filters = null, string $type = self::TYPE_SALES): array
{
- // Проверка типа операции
- if (!in_array($type, [self::TYPE_SALES, self::TYPE_WRITE_OFFS], true)) {
- throw new \InvalidArgumentException("Недопустимый тип операции: $type");
- }
-
// Получение ID видимых магазинов
$storeIds = array_map(fn($store) => $store->id, $this->getVisibleStores());
*/
public function getMonthSubcategoryShareOrWriteOff(string $dateFrom, ?array $filters = null, string $type = self::TYPE_SALES): array
{
- if (!in_array($type, [self::TYPE_SALES, self::TYPE_WRITE_OFFS], true)) {
- throw new \InvalidArgumentException("Недопустимый тип операции: $type");
- }
-
$storeIds = array_map(fn($store) => $store->id, $this->getVisibleStores());
if (!empty($filters['store_id'])) {
$storeIds = array_intersect($storeIds, [(int)$filters['store_id']]);
$productTableJoin = $type === self::TYPE_WRITE_OFFS ? ['wp' => 'write_offs_products'] : ['sp' => 'sales_products'];
$productTableJoinCondition = $type === self::TYPE_WRITE_OFFS ? 'wp.write_offs_id = w.id' : 'sp.check_id = s.id';
+ $date = new \DateTime($dateFrom);
+ $months = [
+ ['between', 'date', $date->modify('-1 year')->format('Y-m-01'), $date->format('Y-m-t')],
+ ['between', 'date', $date->modify('-1 year')->format('Y-m-01'), $date->format('Y-m-t')],
+ ];
+
$query = (new Query())
->select([
'store_id' => 'main.ex_entity_id',
->leftJoin($productTableJoin, $productTableJoinCondition)
->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
->leftJoin('export_import_table ex', $storeJoinCondition)
- ->where(['>=', 'date', $dateFrom])
->andWhere(['ex.entity_id' => $storeIds])
->andWhere(['<>', 'p1c.subcategory', ''])
+ ->andWhere(['or', ...$months])
->groupBy(['ex.entity_id', 'p1c.category', 'p1c.subcategory']),
])
->innerJoin(
->leftJoin($productTableJoin, $productTableJoinCondition)
->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
->leftJoin('export_import_table ex', $storeJoinCondition)
- ->where(['>=', 'date', $dateFrom])
->andWhere(['ex.entity_id' => $storeIds])
->andWhere(['<>', 'p1c.subcategory', ''])
+ ->andWhere(['or', ...$months])
->groupBy(['ex.entity_id'])],
'main.ex_entity_id = totals.store_id'
);
$rows = $query->all();
$result = [];
- foreach ($rows as $row) {
+ foreach ($rows as $row) {
$result[] = [
'store_id' => $row['store_id'],
'category' => $row['category'],
*/
public function getMonthSubcategoryGoal(array $subcategoryShare, array $categoryGoals): array
{
+ echo '<pre>';
+ var_dump($subcategoryShare);
+ echo '</pre>';
+ die();
$indexedGoals = [];
foreach ($categoryGoals as $goal) {
$indexedGoals[$goal['store_id']][$goal['category']] = $goal['goal'];
*/
public function getMonthSpeciesShareOrWriteOff(string $dateFrom, ?array $filters = null, string $type = self::TYPE_SALES): array
{
- if (!in_array($type, [self::TYPE_SALES, self::TYPE_WRITE_OFFS], true)) {
- throw new \InvalidArgumentException("Недопустимый тип операции: $type");
- }
-
$storeIds = array_map(fn($store) => $store->id, $this->getVisibleStores());
if (!empty($filters['store_id'])) {
$storeIds = array_intersect($storeIds, [(int)$filters['store_id']]);
$productTableJoin = $type === self::TYPE_WRITE_OFFS ? ['wp' => 'write_offs_products'] : ['sp' => 'sales_products'];
$productTableJoinCondition = $type === self::TYPE_WRITE_OFFS ? 'wp.write_offs_id = w.id' : 'sp.check_id = s.id';
+ $date = new \DateTime($dateFrom);
+ $months = [
+ ['between', 'date', $date->modify('-1 year')->format('Y-m-01'), $date->format('Y-m-t')],
+ ['between', 'date', $date->modify('-1 year')->format('Y-m-01'), $date->format('Y-m-t')],
+ ];
+
$query = (new Query())
->select([
'store_id' => 'main.ex_entity_id',
->leftJoin($productTableJoin, $productTableJoinCondition)
->leftJoin('products_1c_nomenclature p1c', "p1c.id = $productJoinCondition")
->leftJoin('export_import_table ex', $storeJoinCondition)
- ->where(['>=', key($fromTable) . '.date', $dateFrom])
+ ->andWhere(['or', ...$months])
->andWhere(['ex.entity_id' => $storeIds])
->andWhere(['<>', 'p1c.species', ''])
->groupBy(['ex.entity_id'])],
{
$datePlan = $filters['plan_date'];
$dateFromForCategory = (new \DateTime($datePlan))->modify('-' . (self::CATEGORY_LOOKBACK_MONTHS + self::LOOKBACK_MONTHS) . ' months')->format(self::DATE_FORMAT);
- $dateToForCategory = (new \DateTime($datePlan))->modify('-' . (self::CATEGORY_LOOKBACK_MONTHS + self::LOOKBACK_MONTHS) . ' months')->format(self::DATE_FORMAT);
$dateFrom = (new \DateTime($datePlan))->modify('-' . (self::SUBCATEGORY_LOOKBACK_MONTHS + self::LOOKBACK_MONTHS). ' months')->format(self::DATE_FORMAT);
$monthCategoryShare = $this->getMonthCategoryShareOrWriteOff($dateFromForCategory, $filters);
$monthCategoryGoal = $this->getMonthCategoryGoal($monthCategoryShare, $datePlan, $filters);
- $monthSubcategoryShare = $this->getMonthSubcategoryShareOrWriteOff($dateFrom, $filters);
+ $monthSubcategoryShare = $this->getMonthSubcategoryShareOrWriteOff($datePlan, $filters);
$monthSubcategoryGoal = $this->getMonthSubcategoryGoal($monthSubcategoryShare, $monthCategoryGoal);
- $monthSpeciesShare = $this->getMonthSpeciesShareOrWriteOff($dateFrom, $filters);
+ $monthSpeciesShare = $this->getMonthSpeciesShareOrWriteOff($datePlan, $filters);
$monthSpeciesGoal = $this->getMonthSpeciesGoalDirty($monthSpeciesShare, $monthSubcategoryGoal);
$filtered = array_filter($monthSpeciesGoal, function ($row) use ($filters) {
use yii\widgets\ActiveForm;
use yii_app\records\CityStore;
use yii_app\records\Products1cNomenclature;?>
-<h1 class="ms-3 mb-4"><?= Html::encode("Расчет доли месяца для категорий (month_category_share)") ?></h1>
+ <h1 class="ms-3 mb-4"><?= Html::encode("Расчет доли месяца для категорий (month_category_share)") ?></h1>
<?php $form = ActiveForm::begin(['method' => 'get']); ?>
<div class="row p-3">
<div class="col-md">
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
['attribute' => 'percent', 'label' => 'Доля', 'format' => ['percent', 2]],
],
]); ?>
+
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [
])->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' => 'mm-yyyy',
- ],
- 'options' => [
- 'class' => 'form-control',
- 'placeholder' => 'Плановая дата',
- 'name' => 'plan_date',
- ],
- ])->label('Плановая дата') ?>
+ <?= $form->field(new \yii\base\DynamicModel(['month' => $filters['month'] ?? '']), 'month')->dropDownList(\yii_app\helpers\DateHelper::MONTH_NUMBER_NAMES, [
+ 'prompt' => 'Месяц',
+ 'name' => 'month',
+ ])->label('Плановый месяц') ?>
+ </div>
+
+ <div class="col-md">
+ <?= $form->field(new \yii\base\DynamicModel(['year' => $filters['year'] ?? '']), 'year')->dropDownList(['2025' => 2025, '2026' => 2026], [
+ 'prompt' => 'Год',
+ 'name' => 'year',
+ ])->label('Плановый год') ?>
</div>
<div class="col-md">
<?= $form->field(new \yii\base\DynamicModel(['type' => $filters['type'] ?? '']), 'type')->widget(Select2::class, [