}
}
+ 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()));
+ }
+ }
+ }
+ }
}