]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
Merge branch 'develop' into feature_smirnov_erp-137_motivation_forecast
authorAlexander Smirnov <fredeom@mail.ru>
Fri, 16 Aug 2024 06:53:16 +0000 (09:53 +0300)
committerAlexander Smirnov <fredeom@mail.ru>
Fri, 16 Aug 2024 06:53:16 +0000 (09:53 +0300)
# Conflicts:
# erp24/actions/motivation/IndexAction.php
# erp24/services/MotivationService.php

1  2 
erp24/actions/motivation/IndexAction.php
erp24/services/MotivationService.php

index 09bd09152a9a5c03c659a495c9cd2545ce703d24,dee7445f3db0744690a0e1ab5ec8501c8500f369..65c516374ee655a096e96a5cf30c8e9f5e3711b5
@@@ -90,9 -90,9 +90,12 @@@ class IndexAction extends Actio
          // Подсчитываем стоимость услуг по сборке и по доставке. Позже метод будет перенесён в шедулер
          MotivationService::calculateServiceAssemblyAndDeliveryCost($model->store_id, $model->year, $model->month);
  
+         // Сбор данных по продажам
+         MotivationService::calculateSales($model->store_id, $model->year, $model->month);
 +        // Подсчитываем прогноз за месяц
 +        MotivationService::calculateMonthForecast($model->store_id, $model->year, $model->month);
 +
          $showTable = false;
          $motivationData = [];
          $daysInMonth = null;
index 67f585517f1f98d95096eb3f9b8d7cd125e5d89c,9344aec8d32815a0dfa4154fec1a25ec16bd4a2e..3d358fc4662e46aff452185d528c2fa43f94e51f
@@@ -519,57 -520,68 +519,122 @@@ class MotivationServic
          }
      }
  
+     public static function calculateSales($store_id, $year, $month) {
+         $monthStart = date("Y-m-d 00:00:00", strtotime($year . '-' . $month . '-1'));
+         $monthEnd = date("Y-m-t 23:59:59", strtotime($year . '-' . $month . '-1'));
+         foreach (range(1, 5) as $ind) {
+             $weekStart = date("Y-m-d 00:00:00", strtotime("+" . (($ind - 1) * 7) . ' days', strtotime($monthStart)));
+             $weekEnd = date("Y-m-d 23:59:59", strtotime("+" . ($ind * 7 - 1) . ' days', strtotime($monthStart)));
+             if ($weekEnd > $monthEnd) {
+                 $weekEnd = $monthEnd;
+             }
+             $sales = Sales::find()
+                 ->where(['between', 'date', $weekStart, $weekEnd])
+                 ->andWhere(['store_id' => $store_id])
+                 ->andWhere(['operation' => Sales::OPERATION_SALE])
+                 ->asArray()->all();
+             $salesIds = ArrayHelper::getColumn($sales, 'id');
+             // Ищем чеки-возврат на текущие чеки
+             $returnSales = Sales::find()->where(['operation' => Sales::OPERATION_RETURN, 'sales_check' => $salesIds])->all();
+             $returnSalesIds = ArrayHelper::getColumn($returnSales, 'sales_check');
+             // Offline sales
+             $salesOffline = Sales::find()->select(['SUM(summ) as total'])
+                 ->where(['between', 'date', $weekStart, $weekEnd])
+                 ->andWhere(['order_id' => ['', '0']])
+                 ->andWhere(['store_id' => $store_id])
+                 ->andWhere(['operation' => Sales::OPERATION_SALE])
+                 ->andWhere(['NOT IN', 'id', $returnSalesIds])
+                 ->asArray()->one();
+             // Online sales
+             $salesOnline = Sales::find()->select(['SUM(summ) as total'])
+                 ->where(['between', 'date', $weekStart, $weekEnd])
+                 ->andWhere(['NOT IN', 'order_id', ['', '0']])
+                 ->andWhere(['store_id' => $store_id])
+                 ->andWhere(['operation' => Sales::OPERATION_SALE])
+                 ->andWhere(['NOT IN', 'id', $returnSalesIds])
+                 ->asArray()->one();
+             $motivation = Motivation::find()->where(['store_id' => $store_id, 'year' => $year, 'month' => $month])->one();
+             $motivationValueGroup = MotivationValueGroup::find()->where(['alias' => 'week' . $ind])->one();
+             foreach (['Оффлайн продажи', 'Онлайн продажи'] as $topicInd => $topic) {
+                 $motivationCostsItem = MotivationCostsItem::find()->where(['name' => $topic])->one();
+                 /** @var $motivationCostsItem MotivationCostsItem */
+                 if ($motivation) {
+                     $motivationValue = MotivationValue::find()->where(['motivation_id' => $motivation->id,
+                         'motivation_group_id' => $motivationValueGroup->id, 'value_id' => $motivationCostsItem->code])->one();
+                     if (!$motivationValue) {
+                         $motivationValue = new MotivationValue;
+                         $motivationValue->motivation_id = $motivation->id;
+                         $motivationValue->motivation_group_id = $motivationValueGroup->id;
+                         $motivationValue->value_id = $motivationCostsItem->code;
+                         $motivationValue->value_type = $motivationCostsItem->data_type;
+                     }
+                     $motivationValue->value_float = [$salesOffline, $salesOnline][$topicInd]['total'];
+                     $motivationValue->save();
+                     if ($motivationValue->getErrors()) {
+                         throw new \Exception(Json::encode($motivationValue->getErrors()));
+                     }
+                 }
+             }
+         }
+     }
++
 +    public static function calculateMonthForecast($store_id, $year, $month) {
 +        $motivationCostsItem = MotivationCostsItem::find()->all();
 +        $motivationCostsItemCodes = ArrayHelper::getColumn($motivationCostsItem, 'code');
 +        $additionalItemsKeys = array_keys(self::$additionalItems);
 +
 +        $items = array_merge($motivationCostsItemCodes, $additionalItemsKeys);
 +
 +        $motivationValueGroups = [];
 +        foreach (range(1, 5) as $ind) {
 +            $motivationValueGroups []= MotivationValueGroup::find()->where(['alias' => 'week' . $ind])->one();
 +        }
 +        /** @var $motivationValueGroups MotivationValueGroup[] */
 +
 +        $motivationValueGroupForecast = MotivationValueGroup::find()->where(['alias' => 'forecast'])->one();
 +        /** @var $motivationValueGroupForecast MotivationValueGroup */
 +
 +        $motivation = Motivation::find()->where(['store_id' => $store_id, 'year' => $year, 'month' => $month])->one();
 +        foreach ($items as $code) {
 +            if ($motivation) {
 +                $motivationValue = MotivationValue::find()->where(['motivation_id' => $motivation->id,
 +                    'motivation_group_id' => $motivationValueGroupForecast->id, 'value_id' => $code])->one();
 +                $sum = 0;
 +                $sum_type = MotivationCostsItem::DATA_TYPE_INT;
 +                foreach (range(1, 5) as $ind) {
 +                    $mv = MotivationValue::find()->where(['motivation_id' => $motivation->id,
 +                        'motivation_group_id' => $motivationValueGroups[$ind-1]->id, 'value_id' => $code])->one();
 +                    /** @var $mv MotivationValue */
 +                    if ($mv) {
 +                        switch ($mv->value_type) {
 +                            case MotivationCostsItem::DATA_TYPE_INT: { $sum += $mv->value_int; break; }
 +                            case MotivationCostsItem::DATA_TYPE_FLOAT: { $sum += $mv->value_float; $sum_type = MotivationCostsItem::DATA_TYPE_FLOAT; break; }
 +                            case MotivationCostsItem::DATA_TYPE_STRING: { throw new \Exception(Json::encode("Тип string невозможен для вычисления прогноза")); }
 +                        };
 +                    }
 +                }
 +                if (!$motivationValue) {
 +                    $motivationValue = new MotivationValue;
 +                    $motivationValue->motivation_id = $motivation->id;
 +                    $motivationValue->motivation_group_id = $motivationValueGroupForecast->id;
 +                    $motivationValue->value_id = $code;
 +                }
 +                $motivationValue->value_type = $sum_type;
 +                switch ($sum_type) {
 +                    case MotivationCostsItem::DATA_TYPE_INT: { $motivationValue->value_int = $sum; break; }
 +                    default: { $motivationValue->value_float = $sum; break; }
 +                }
 +                $motivationValue->save();
 +                if ($motivationValue->getErrors()) {
 +                    throw new \Exception(Json::encode($motivationValue->getErrors()));
 +                }
 +            }
 +        }
 +    }
  }