]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Merge branch 'refs/heads/develop' into feature_fomichev_erp_424_change_marketplace...
authorfomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 19 Jun 2025 11:39:41 +0000 (14:39 +0300)
committerfomichev <vladimir.fomichev@erp-flowers.ru>
Thu, 19 Jun 2025 11:39:41 +0000 (14:39 +0300)
# Conflicts:
# erp24/commands/CronController.php

1  2 
erp24/commands/CronController.php

index 4ae41c1074399463b21d6511ad1e17a56817a88c,db9af7bfd2dbe1fbb486cab1bdbb3e7b17bd296f..401457efac6f643b62100d1e10f67d1f6a1fdd6e
@@@ -90,18 -98,7 +98,18 @@@ class CronController extends Controlle
              $statusesData = [];
              foreach ($statuses as $status) {
                  /* @var $status MarketplaceOrder1cStatuses */
-                 $statusesData []= [
 +                $relftions = $status->relationsFrom;
 +                $relationsToSend = [];
 +                foreach ($relftions as $relation) {
 +                    $statusTo = MarketplaceOrder1cStatuses::find()->where(['id' => $relation['status_id_to']])->one();
 +                    if(!$statusTo) {
 +                        continue;
 +                    }
 +                    $relationsToSend[] =
 +                        $statusTo->status_id;
 +                }
+                 $statusesData [] = [
 +                    'index_number' => $status->posit,
                      'status_name' => $status->status,
                      'hint' => $status->status_instruction,
                      'status_id' => $status->status_id,
          return ExitCode::OK;
      }
  
 -                    $total = (float) sprintf('%.2f', $total); 
+     public function actionAutoplannogrammaCalculate(): void
+     {
+         $date = new DateTime();
+         $date->modify('+2 months');
+         $planDate = $date->format('Y-m-01');
+         $month = (int)$date->format('m');
+         $year = (int)$date->format('Y');
+         $service = new AutoPlannogrammaService();
+         $stores = CityStore::find()->where(['visible' => CityStore::IS_VISIBLE])->all();
+         $this->stdout("Начало расчетов автопланограммы для $planDate\n", BaseConsole::FG_GREEN);
+         foreach ($stores as $store) {
+             $this->stdout("Начало расчетов автопланограммы для магазина ID: {$store->id} ({$store->name})\n", BaseConsole::FG_YELLOW);
+             try {
+                 $forecastParams = [
+                     'month' => $month,
+                     'year' => $year,
+                     'type' => AutoPlannogrammaService::TYPE_SALES,
+                     'store_id' => $store->id,
+                     'category' => null,
+                     'subcategory' => null,
+                     'species' => null,
+                     'plan_date' => $planDate
+                 ];
+                 $forecast = $service->calculateFullForecastForWeek($forecastParams);
+                 $writeOffsForecast = $service->getWeeklyProductsWriteoffsForecast($month, $year, $forecast, $store->id);
+                 $salesForecast = $service->getWeeklyBouquetProductsSalesForecast($month, $year, $store->id);
+                 $this->stdout("Рассчитана автопланограмма для магазина {$store->name}\n", BaseConsole::FG_GREEN);
+                 $existingRecords = Autoplannogramma::find()
+                     ->where([
+                         'month' => $month,
+                         'year' => $year,
+                         'store_id' => $store->id,
+                         'week' => array_unique(array_column($forecast, 'week'))
+                     ])
+                     ->indexBy(fn($record) => $record->week . '_' . $record->product_id)
+                     ->all();
+                 foreach ($forecast as $item) {
+                     $key = $item['week'] . '_' . $item['product_id'];
+                     $model = $existingRecords[$key] ?? new Autoplannogramma();
+                     $productId = $item['product_id'];
+                     $week = $item['week'];
+                     $quantity = (float)($item['forecast_week_pieces'] ?? 0);
+                     $details = [];
+                     $total = $quantity;
+                     if (!empty($writeOffsForecast[$productId][$week]['writeOffs'])) {
+                         $writeOffs = $writeOffsForecast[$productId][$week]['writeOffs'];
+                         $details['writeOffs']['quantity'] = $writeOffs;
+                         $total += is_array($writeOffs) ? array_sum($writeOffs) : (float)$writeOffs;
+                     }
+                     foreach (['offline', 'online', 'marketplace'] as $type) {
+                         if (!isset($salesForecast[$store->id][$productId][$type])) {
+                             $details[$type] = ['share' => 0, 'quantity' => 0, 'groups' => []];
+                             continue;
+                         }
+                         $data = $salesForecast[$store->id][$productId][$type];
+                         if (!is_array($data)) {
+                             $details[$type] = ['share' => 0, 'quantity' => 0, 'groups' => []];
+                             continue;
+                         }
+                         $block = [];
+                         $groups = [];
+                         $share = isset($salesForecast[$store->id][$type]['share']) ? (float)$salesForecast[$store->id][$type]['share'] : 0;
+                         $block['share'] = $share;
+                         $block['quantity'] = (float) sprintf('%.2f', round($quantity * $share, 2)); // Нормализует -0 до 0
+                         $total += $block['quantity'];
+                         foreach ($data as $k => $v) {
+                             $val = (float)$v;
+                             $groups[$k] = $val;
+                             $total += $val;
+                         }
+                         $block['groups'] = !empty($groups) ? $groups : [];
+                         $details[$type] = $block;
+                     }
+                     $details['forecast'] = ['quantity' => $quantity];
++                    $total = (float) sprintf('%.2f', $total);
+                     $needsUpdate = !$model->isNewRecord && (
+                             $model->calculate !== $quantity ||
+                             ceil((float)$model->total) !== ceil($total) ||
+                             json_encode($model->details, JSON_UNESCAPED_UNICODE) !== json_encode($details, JSON_UNESCAPED_UNICODE)
+                         );
+                     if ($model->isNewRecord || $needsUpdate) {
+                         $model->setAttributes([
+                             'month' => $month,
+                             'year' => $year,
+                             'week' => $week,
+                             'product_id' => $productId,
+                             'store_id' => $store->id,
+                             'is_archive' => false,
+                             'capacity_type' => 1,
+                             'details' => json_encode($details, JSON_UNESCAPED_UNICODE),
+                             'calculate' => $quantity,
+                             'modify' => ceil($total),
+                             'total' => ceil($total)
+                         ]);
+                         if (!$model->save()) {
+                             $errors = implode('; ', array_map(
+                                 fn($attr, $attrErrors) => "$attr: " . implode(', ', $attrErrors),
+                                 array_keys($model->getErrors()),
+                                 $model->getErrors()
+                             ));
+                             $this->stderr("Ошибка при сохранении модели: $errors\n", BaseConsole::FG_RED);
+                             Yii::error("Ошибка сохранения Autoplannogramma: $errors", __METHOD__);
+                         }
+                     }
+                 }
+                 $this->stdout("Сохранена автопланограмма для магазина {$store->name}\n", BaseConsole::FG_GREEN);
+             } catch (Throwable $e) {
+                 $this->stderr("Ошибка при расчёте прогноза: {$e->getMessage()}\n", BaseConsole::FG_RED);
+                 Yii::error("Ошибка при расчёте прогноза: " . $e->getMessage(), __METHOD__);
+                 continue;
+             }
+         }
+         $this->stdout("Расчет и сохранение автопланограммы завершены\n", BaseConsole::FG_GREEN);
+     }
  }