From: fomichev Date: Tue, 1 Jul 2025 13:33:48 +0000 (+0300) Subject: Правки пересчета X-Git-Url: https://gitweb.erp-flowers.ru/?a=commitdiff_plain;h=8814d213a8d59847e986b787de1857ae83e9e66a;p=erp24_rep%2Fyii-erp24%2F.git Правки пересчета --- diff --git a/erp24/commands/CronController.php b/erp24/commands/CronController.php index e1eb5e25..6111b05f 100644 --- a/erp24/commands/CronController.php +++ b/erp24/commands/CronController.php @@ -1780,7 +1780,10 @@ class CronController extends Controller $log->month = (int)$task['month']; $log->active = 1; $log->date_start = date('Y-m-d H:i:s'); - $log->save(false); + if (!$log->save()) { + Yii::error(json_encode($log->getErrors(), JSON_UNESCAPED_UNICODE)); + LogService::apiErrorLog(json_encode(["error_id" => 8, "error" => $log->getErrors()], JSON_UNESCAPED_UNICODE)); + } $service = new AutoPlannogrammaService(); $year = (int)$task['year']; @@ -1906,7 +1909,10 @@ class CronController extends Controller $log->active = 0; $log->date_finish = date('Y-m-d H:i:s'); $log->status = 1; - $log->save(false); + if (!$log->save()) { + Yii::error(json_encode($log->getErrors(), JSON_UNESCAPED_UNICODE)); + LogService::apiErrorLog(json_encode(["error_id" => 8, "error" => $log->getErrors()], JSON_UNESCAPED_UNICODE)); + } $this->stdout("Расчет для магазина {$storeId} закончен\n"); return ExitCode::OK; @@ -1923,8 +1929,11 @@ class CronController extends Controller $log->active = 0; $log->date_finish = date('Y-m-d H:i:s'); $log->status = 2; - $log->save(false); - + if (!$log->save()) { + Yii::error(json_encode($log->getErrors(), JSON_UNESCAPED_UNICODE)); + LogService::apiErrorLog(json_encode(["error_id" => 8, "error" => $log->getErrors()], JSON_UNESCAPED_UNICODE)); + } + Yii::$app->cache->delete("apRecalculateTask"); $this->stderr("Ошибка в ходе расчета: {$e->getMessage()}\n"); return ExitCode::UNSPECIFIED_ERROR; } diff --git a/erp24/controllers/CategoryPlanController.php b/erp24/controllers/CategoryPlanController.php index 0a5f3648..bc9dc24c 100644 --- a/erp24/controllers/CategoryPlanController.php +++ b/erp24/controllers/CategoryPlanController.php @@ -18,6 +18,7 @@ use yii_app\records\ExportImportTable; use yii_app\records\Products1cNomenclature; use yii_app\records\Sales; use yii_app\records\SalesWriteOffsPlan; +use yii_app\records\ScriptLauncherLog; use yii_app\records\StoreDynamic; use yii_app\records\WriteOffs; use yii_app\records\WriteOffsErp; @@ -25,404 +26,8 @@ use yii_app\services\AutoPlannogrammaService; use yii_app\services\StorePlanService; class CategoryPlanController extends Controller { - public function actionIndex() - { - $model = DynamicModel::validateData([ - 'year' => date('Y'), - 'month' => date('m'), - 'store_id' => null, - 'city_id' => null, - 'region_id' => null, - 'raion_id' => null, - 'store_type_id' => null, - 'territory_manager_id' => null, - 'kshf_id' => null, - ], [ - [[ - 'year', 'month', 'store_id', 'city_id', 'region_id', 'raion_id', 'store_type_id', - 'territory_manager_id', 'kshf_id' - ], 'safe'] - ]); - - $model->load(Yii::$app->request->get()); - - $service = new AutoPlannogrammaService(); - $isEditable = date($model->year . '-' . $model->month . '-d') > date('Y-m-d') && ( - (date('d') < 27) || (date('Y-m-d', strtotime('-1 month', strtotime(date($model->year . '-' . $model->month . '-d')))) > date('Y-m-d'))); - - $categoryPlan = CategoryPlan::find()->where(['year' => $model->year, 'month' => $model->month, 'store_id' => $model->store_id])->indexBy('category')->asArray()->all(); - $types = []; - $table = []; - $tableOnline = []; - $tableWriteOffs = []; - $years = []; - for ($i = 3; $i >= 0; $i--) { - $year = date("Y") - $i; - $years [$year] = $year; - } - $stores = ArrayHelper::map(CityStore::find()->andWhere(['visible' => '1'])->all(), 'id', 'name'); - $salesWriteOffsPlan = SalesWriteOffsPlan::find()->where(['year' => $model->year, 'month' => $model->month, 'store_id' => $model->store_id])->one(); - /////////////////////////// CHAT GPT STUFF /////////////////////////////////// - //var_dump(Yii::$app->request->get()); die(); - if ( - $model->year - && $model->month - && $model->store_id - ) { - if (Yii::$app->request->get('delete') === '1' - ) { - $count = Yii::$app->db - ->createCommand() - ->delete('erp24.category_plan', [ - 'year' => $model->year, - 'month' => $model->month, - 'store_id' => $model->store_id, - ]) - ->execute(); - - Yii::$app->session->setFlash( - $count ? 'success' : 'info', - $count - ? "Удалено {$count} записей." - : 'Ничего не удалено.' - ); - - $params = [ - 'DynamicModel' => $model->attributes, - ]; - - $params['DynamicModel'] = array_filter($params['DynamicModel'], function($v) { - return $v !== null && $v !== ''; - }); - - return $this->redirect(array_merge( - ['index'], - $params - )); - - } - $currentDate = new \DateTime(date($model->year . '-' . $model->month . '-01')); - - $startDate = (clone $currentDate)->modify('-4 months')->modify('first day of this month'); - - $endDate = (clone $startDate)->modify('+2 months')->modify('last day of this month'); - - $date_start = $startDate->format('Y-m-d'); - $date_end = $endDate->format('Y-m-d'); - - $sales = Sales::find()->alias('s')->select([ - "COUNT(*) as cnt", - "SUM(CASE WHEN operation='Продажа' THEN sp.summ ELSE (CASE WHEN operation='Возврат' THEN -sp.summ ELSE 0 END) END) as total", - "s.store_id", - "p1cn.category as type", - "TO_CHAR(s.date, 'YYYY-MM') as month" - ]) - ->leftJoin('sales_products sp', 's.id = sp.check_id') - ->leftJoin('products_1c p1c', 'p1c.id = sp.product_id') - ->leftJoin('products_1c_nomenclature p1cn', 'p1cn.id = sp.product_id') - ->where(['between', 's.date', $date_start, $date_end]) - ->andWhere(['order_id' => ['', '0']]) - ->andWhere(['p1c.components' => '']) - ->andWhere(['not in', 'p1cn.category', ['', 'букет', 'сборка', 'сервис']]) - ->andWhere(['s.store_id' => $model->store_id]) - ->groupBy([ - 's.store_id', - "TO_CHAR(s.date, 'YYYY-MM')", - "p1cn.category" - ]) - ->orderBy(['month' => SORT_ASC, 'type' => SORT_ASC]) - ->asArray() - ->all(); - - $salesMatrixOffline = Sales::find()->alias('s')->select([ - "COUNT(*) as cnt", - "SUM(CASE WHEN operation='Продажа' THEN sp.summ ELSE (CASE WHEN operation='Возврат' THEN -sp.summ ELSE 0 END) END) as total", - "s.store_id", - "p1c.type as type", - "TO_CHAR(s.date, 'YYYY-MM') as month" - ]) - ->leftJoin('sales_products sp', 's.id = sp.check_id') - ->leftJoin('products_1c p1c', 'p1c.id = sp.product_id') - ->where(['between', 's.date', $date_start, $date_end]) - ->andWhere(['order_id' => ['', '0']]) - ->andWhere(['p1c.type' => 'Матрица']) - ->andWhere(['s.store_id' => $model->store_id]) - ->groupBy([ - 's.store_id', - "TO_CHAR(s.date, 'YYYY-MM')", - "p1c.type" - ]) - ->orderBy(['month' => SORT_ASC, 'type' => SORT_ASC]) - ->asArray() - ->all(); - - - $compoundSalesData = []; - for ($i = 0; $i < 3; $i++) { - $dateToStart = (clone $startDate)->modify("+$i months"); - $compoundSalesYear = $dateToStart->format('Y'); - $compoundSalesMonth = $dateToStart->format('m'); - $compoundSales = $service->getProductsComponentsInCategory($model->store_id, $compoundSalesMonth, $compoundSalesYear); - $offline = []; - $online = []; - foreach ($compoundSales as $compoundSale) { - if (in_array($compoundSale['order_id'], ['', '0'], true)) { - $offline[] = $compoundSale; - } else { - $online[] = $compoundSale; - } - } - $dateKey = $compoundSalesYear . '-' . $compoundSalesMonth; - $offlineCompoundSum = $service->sumProductsComponentsByGroup($offline, AutoPlannogrammaService::TYPE_SALES); - $onlineCompoundSum = $service->sumProductsComponentsByGroup($online, AutoPlannogrammaService::TYPE_SALES); - - $compoundSalesData['offline'][$dateKey] = $offlineCompoundSum; - $compoundSalesData['online'][$dateKey] = $onlineCompoundSum; - - - } - //var_dump($compoundSalesData); die(); - - - $mnths = []; - foreach ($sales as $sale) { - $mnths[$sale['month']] = 1; - $types[$sale['type']] = 1; - } - $mnths = array_keys($mnths); - - sort($mnths); - - $weights = []; - foreach ($mnths as $ind => $month) { - $weights[$month] = $ind + 1; - } - - foreach ($sales as $sale) { - $table[$sale['store_id']][$sale['type']] = ($table[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] ; - } - foreach ($salesMatrixOffline as $saleMatrix) { - $types[$saleMatrix['type']] = 1; - $table[$saleMatrix['store_id']][$saleMatrix['type']] = ($table[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] ; - } - //var_dump($table); die(); - foreach ($compoundSalesData['offline'] as $monthKey => $categories) { - $w = $weights[$monthKey] ?? 0; - foreach ($categories as $item) { - $store = $item['store_id']; - $type = $item['category']; - $sum = (float)$item['sum']; - $types[$item['category']] = 1; - $table[$store][$type] = ($table[$store][$type] ?? 0) - + $w * $sum ; - } - } - - $offlinePlannedSales = self::calculatePlannedSales($table, $salesWriteOffsPlan->offline_sales_plan); - - $salesOnline = Sales::find()->alias('s')->select([ - "COUNT(*) as cnt", - "SUM(CASE WHEN operation='Продажа' THEN sp.summ ELSE (CASE WHEN operation='Возврат' THEN -sp.summ ELSE 0 END) END) as total", - "s.store_id", - "p1cn.category as type", - "TO_CHAR(s.date, 'YYYY-MM') as month" - ]) - ->leftJoin('sales_products sp', 's.id = sp.check_id') - ->leftJoin('products_1c p1c', 'p1c.id = sp.product_id') - ->leftJoin('products_1c_nomenclature p1cn', 'p1cn.id = sp.product_id') - ->where(['between', 's.date', $date_start, $date_end]) - ->andWhere(['not in', 'order_id', ['', '0']]) - ->andWhere(['s.store_id' => $model->store_id]) - ->andWhere(['p1c.components' => '']) - ->andWhere(['not in', 'p1cn.category', ['', 'букет', 'сборка', 'сервис']]) - ->groupBy([ - 's.store_id', - "TO_CHAR(s.date, 'YYYY-MM')", - "p1cn.category" - ]) - ->orderBy(['month' => SORT_ASC, 'type' => SORT_ASC]) - ->asArray() - ->all(); - - - $salesMatrixOnline = Sales::find()->alias('s')->select([ - "COUNT(*) as cnt", - "SUM(CASE WHEN operation='Продажа' THEN sp.summ ELSE (CASE WHEN operation='Возврат' THEN -sp.summ ELSE 0 END) END) as total", - "s.store_id", - "p1c.type as type", - "TO_CHAR(s.date, 'YYYY-MM') as month" - ]) - ->leftJoin('sales_products sp', 's.id = sp.check_id') - ->leftJoin('products_1c p1c', 'p1c.id = sp.product_id') - ->where(['between', 's.date', $date_start, $date_end]) - ->andWhere(['not in', 'order_id', ['', '0']]) - ->andWhere(['p1c.type' => 'Матрица']) - ->andWhere(['s.store_id' => $model->store_id]) - ->groupBy([ - 's.store_id', - "TO_CHAR(s.date, 'YYYY-MM')", - "p1c.type" - ]) - ->orderBy(['month' => SORT_ASC, 'type' => SORT_ASC]) - ->asArray() - ->all(); - - - foreach ($salesOnline as $sale) { - $types[$sale['type']] = 1; - $tableOnline[$sale['store_id']][$sale['type']] = ($tableOnline[$sale['store_id']][$sale['type']] ?? 0) + $weights[$sale['month']] * $sale['total'] ; - } - foreach ($salesMatrixOnline as $saleMatrix) { - $types[$saleMatrix['type']] = 1; - $tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] = ($tableOnline[$saleMatrix['store_id']][$saleMatrix['type']] ?? 0) + $weights[$saleMatrix['month']] * $saleMatrix['total'] ; - } - - foreach ($compoundSalesData['online'] as $monthKey => $categories) { - $w = $weights[$monthKey] ?? 0; - foreach ($categories as $item) { - $store = $item['store_id']; - $type = $item['category']; - $sum = (float)$item['sum']; - $types[$item['category']] = 1; - $tableOnline[$store][$type] = ($tableOnline[$store][$type] ?? 0) - + $w * $sum ; - } - } - - $onlinePlannedSales = self::calculatePlannedSales($tableOnline, $salesWriteOffsPlan->online_sales_shop_plan); - - - $eit = ExportImportTable::find()->where(['entity' => 'city_store', 'export_id' => 1, 'entity_id' => $model->store_id])->one(); - $store_id = $eit->export_val ?? ''; - $writeOffs = WriteOffs::find()->alias('wo')->select([ - 'sum(wop.summ) as total', - "p1cn.category as p1ctype", - 'ex.entity_id AS store_id', - "TO_CHAR(wo.date, 'YYYY-MM') as month" - ]) - ->leftJoin('write_offs_products wop', 'wop.write_offs_id = wo.id') - ->leftJoin('products_1c p1c', 'p1c.id = wop.product_id') - ->leftJoin('products_1c_nomenclature p1cn', 'p1cn.id = wop.product_id') - ->leftJoin('export_import_table ex', 'ex.export_val = wo.store_id') - ->where(['between', 'wo.date', $date_start, $date_end]) - ->andWhere(['wo.type' => WriteOffsErp::WRITE_OFFS_TYPE_BRAK]) - ->andWhere(['p1c.components' => '']) - ->andWhere(['not in', 'p1cn.category', ['', 'букет', 'сборка', 'сервис']]) - ->andWhere(['wo.store_id' => $store_id]) - ->groupBy([ - "month", - 'ex.entity_id', - "p1cn.category" - ]) - ->asArray()->all(); - - $writeOffsMatrix = WriteOffs::find()->alias('wo')->select([ - 'sum(wop.summ) as total', - 'ex.entity_id AS store_id', - "p1c.type as p1ctype", - "TO_CHAR(wo.date, 'YYYY-MM') as month" - ]) - ->leftJoin('write_offs_products wop', 'wop.write_offs_id = wo.id') - ->leftJoin('products_1c p1c', 'p1c.id = wop.product_id') - ->leftJoin('products_1c_nomenclature p1cn', 'p1cn.id = wop.product_id') - ->leftJoin('export_import_table ex', 'ex.export_val = wo.store_id') - ->where(['between', 'wo.date', $date_start, $date_end]) - ->andWhere(['wo.type' => WriteOffsErp::WRITE_OFFS_TYPE_BRAK]) - ->andWhere(['p1c.type' => 'Матрица']) - ->andWhere(['wo.store_id' => $store_id]) - ->groupBy([ - "month", - 'ex.entity_id', - "p1c.type" - ]) - ->asArray()->all(); - - - $compoundWriteOffsData = []; - for ($i = 0; $i < 3; $i++) { - - $dateToStartWriteOffs = (clone $startDate)->modify("+$i months"); - $compoundSalesYear = $dateToStartWriteOffs->format('Y'); - $compoundSalesMonth = $dateToStartWriteOffs->format('m'); - $compoundWriteOffs = $service->getProductsComponentsInCategory($model->store_id, $compoundSalesMonth, $compoundSalesYear, AutoPlannogrammaService::TYPE_WRITE_OFFS); - - $writeoffsCompoundSum = $service->sumProductsComponentsByGroup($compoundWriteOffs, AutoPlannogrammaService::TYPE_WRITE_OFFS); - - $dateKey = $compoundSalesYear . '-' . $compoundSalesMonth; - $compoundWriteOffsData[$dateKey] = $writeoffsCompoundSum; - } - - - foreach ($writeOffs as $writeoff) { - $types[$writeoff['p1ctype']] = 1; - $tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] = ($tableWriteOffs[$writeoff['store_id']][$writeoff['p1ctype']] ?? 0) + $weights[$writeoff['month']] * $writeoff['total']; - } - - foreach ($writeOffsMatrix as $writeOffMatrix) { - $types[$writeOffMatrix['p1ctype']] = 1; - $tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] = ($tableWriteOffs[$writeOffMatrix['store_id']][$writeOffMatrix['p1ctype']] ?? 0) + $weights[$writeOffMatrix['month']] * $writeOffMatrix['total']; - } - - foreach ($compoundWriteOffsData as $monthKey => $categories) { - $w = $weights[$monthKey] ?? 0; - foreach ($categories as $item) { - $store = $item['store_id']; - $type = $item['category']; - $sum = (float)$item['sum']; - $types[$item['category']] = 1; - $tableWriteOffs[$store][$type] = ($tableWriteOffs[$store][$type] ?? 0) - + $w * $sum ; - } - } - $plannedWriteOffs = self::calculatePlannedSales($tableWriteOffs, $salesWriteOffsPlan->write_offs_plan); - $types = array_keys($types); - ///////////////////////////////////////////////////////////////////////////////////// - - foreach ($types as $type) { - if (!empty($type) && !isset($categoryPlan[$type])) { - $categoryPlanNew = new CategoryPlan; - $categoryPlanNew->year = $model->year; - $categoryPlanNew->month = $model->month; - $categoryPlanNew->store_id = $model->store_id; - $categoryPlanNew->category = $type; - $categoryPlanNew->offline = $offlinePlannedSales[$model->store_id][$type] ?? 0; - $categoryPlanNew->internet_shop = $onlinePlannedSales[$model->store_id][$type] ?? 0; - $categoryPlanNew->marketplace = 0; - $categoryPlanNew->write_offs = $plannedWriteOffs[$model->store_id][$type] ?? 0; - $categoryPlanNew->created_at = date('Y-m-d HH:i:s'); - $categoryPlanNew->updated_at = date('Y-m-d HH:i:s'); - $categoryPlanNew->created_by = Yii::$app->user->id; - $categoryPlanNew->updated_by = Yii::$app->user->id; - $categoryPlanNew->save(); - if ($categoryPlanNew->getErrors()) { - throw new Exception(Json::encode($categoryPlanNew->getErrors())); - } - } - } - - $categoryPlan = CategoryPlan::find()->where(['year' => $model->year, 'month' => $model->month, 'store_id' => $model->store_id])->indexBy('category')->asArray()->all(); - - - $order = [ - 'Срезка' => 1, - 'Сухоцветы' => 2, - 'Горшечные_растения' => 3, - 'Сопутствующие_товары' => 4, - 'Упаковка' => 5, - 'Матрица' => 6, - ]; - - usort($types, function ($a, $b) use ($order) { - return ($order[$a] ?? 999) <=> ($order[$b] ?? 999); - }); - - } - - return $this->render('index', compact('model', 'years', 'stores', 'table', 'tableOnline', - 'tableWriteOffs', 'types', 'salesWriteOffsPlan', 'isEditable', 'categoryPlan')); - } - public function actionNew() + public function actionIndex() { $model = DynamicModel::validateData([ 'year' => date('Y'), @@ -483,20 +88,16 @@ class CategoryPlanController extends Controller { ? "Удалено {$count} записей." : 'Ничего не удалено.' ); - Yii::$app->cache->set('needRecalc', time(), 3600); - - $params = [ - 'DynamicModel' => $model->attributes, - ]; - - $params['DynamicModel'] = array_filter($params['DynamicModel'], function($v) { - return $v !== null && $v !== ''; - }); - - return $this->redirect(array_merge( - ['new'], - $params - )); + Yii::$app->cache->set('needRecalc', 'Recalc', 3600); + Yii::$app->cache->delete("apRecalculateTask"); + if (Yii::$app->request->isAjax) { + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + return [ + 'status' => 'ok', + 'message' => "Удалено {$count} записей.", + 'data' => Yii::$app->cache->get('needRecalc') + ]; + } } @@ -650,12 +251,29 @@ class CategoryPlanController extends Controller { $categoryPlanNew->updated_at = date('Y-m-d HH:i:s'); $categoryPlanNew->created_by = Yii::$app->user->id; $categoryPlanNew->updated_by = Yii::$app->user->id; - $categoryPlanNew->save(); - if ($categoryPlanNew->getErrors()) { + if ( $categoryPlanNew->save()) { + $recalcFlag = Yii::$app->cache->get('needRecalc'); + if ($recalcFlag) { + $taskName = "apRecalculateTask"; + + $cacheValue = [ + 'taskName' => $taskName, + 'year' => $model->year, + 'month' => $model->month, + 'storeId' => $model->store_id, + 'status' => 'pending', + 'startTime' => date('Y-m-d H:i:s'), + 'progress' => 0, + 'error' => null + ]; + Yii::$app->cache->set($taskName, $cacheValue, 3600); + Yii::$app->cache->delete('needRecalc'); + } + } else { throw new Exception(Json::encode($categoryPlanNew->getErrors())); } - $recalcFlag = Yii::$app->cache->get('needRecalc'); + } } @@ -677,7 +295,7 @@ class CategoryPlanController extends Controller { } - return $this->render('new', compact('model', 'years', 'stores', 'table', 'tableOnline', + return $this->render('index', compact('model', 'years', 'stores', 'table', 'tableOnline', 'tableWriteOffs', 'types', 'salesWriteOffsPlan', 'isEditable', 'categoryPlan')); } @@ -972,28 +590,42 @@ class CategoryPlanController extends Controller { $year = (int)Yii::$app->request->get('year'); $month = (int)Yii::$app->request->get('month'); $store = (int)Yii::$app->request->get('store_id'); - $taskName = "apRecalculateTask"; - - $cacheValue = [ - 'taskName' => $taskName, - 'year' => $year, - 'month' => $month, - 'storeId' => $store, - 'status' => 'pending', - 'startTime' => date('Y-m-d H:i:s'), - 'progress' => 0, - 'error' => null - ]; - Yii::$app->cache->set($taskName, $cacheValue, 3600); - - return $this->asJson(['status' => 'started', 'data' => Yii::$app->cache->get('apRecalculateTask') ]); + $scriptLauncherLog = ScriptLauncherLog::find() + ->andWhere(['name' => "taskApRecalculate"]) + ->orderBy(['created_at' => SORT_DESC]) + ->asArray() + ->limit(1) + ->one(); + if ($scriptLauncherLog && $scriptLauncherLog['active'] == 1) { + return $this->asJson(['status' => 'running' ]); + } else { + $taskName = "apRecalculateTask"; + + $cacheValue = [ + 'taskName' => $taskName, + 'year' => $year, + 'month' => $month, + 'storeId' => $store, + 'status' => 'pending', + 'startTime' => date('Y-m-d H:i:s'), + 'progress' => 0, + 'error' => null + ]; + Yii::$app->cache->set($taskName, $cacheValue, 3600); + + return $this->asJson(['status' => 'started', 'data' => Yii::$app->cache->get('apRecalculateTask') ]); + } + } public function actionCheckTask() { $task = Yii::$app->cache->get('apRecalculateTask'); - + if ($task && $task['status'] === 'done') { + Yii::$app->cache->delete("apRecalculateTask"); + } if (!$task) { + return $this->asJson(['status' => 'not_found']); } diff --git a/erp24/views/category-plan/index.php b/erp24/views/category-plan/index.php index a7dc4de8..9cdcc31e 100644 --- a/erp24/views/category-plan/index.php +++ b/erp24/views/category-plan/index.php @@ -38,19 +38,19 @@ input[readonly] {

План по категориям

-

Yii::$app->request->url] - ), - ['class' => 'ms-3 mb-3 pb-3', 'target' => '_blank', 'title' => 'Открыть документацию'] - ) ?>

+

Yii::$app->request->url] + ), + ['class' => 'ms-3 mb-3 pb-3', 'target' => '_blank', 'title' => 'Открыть документацию'] + ) ?>

'filter-form', 'method' => 'GET', - 'action' => '/category-plan' + 'action' => '/category-plan/index' ]) ?>
@@ -159,10 +159,22 @@ input[readonly] {
'btn btn-secondary'])?> - month && $model->year && $model->store_id) { ?> - 'btn btn-danger ms-2', + +
+
+
+ + + + store_id)): ?> +
+
+

store_id]?>

+ month && $model->year && $model->store_id) { ?> + 'btn btn-danger m-2', 'name' => 'delete', + 'id' => 'delete', 'value' => 1, 'data' => [ 'confirm' => 'Вы уверены, что хотите вернуть автоплан за ' @@ -170,8 +182,9 @@ input[readonly] { ], ]) ?> - 'btn btn-success ms-2', + + 'btn btn-success m-2', 'disabled' => true, 'id' => 'rebuild', 'name' => 'rebuild', @@ -182,36 +195,28 @@ input[readonly] { ], ]) ?> - -
-
- - - - - store_id)): ?> -
-
-

store_id]?>

+ +
+
-
- - offline_sales_plan; - $online_sale = $salesWriteOffsPlan->online_sales_shop_plan; - $write_offs = $salesWriteOffsPlan->write_offs_plan; - ?> - +
+
+ offline_sales_plan; + $online_sale = $salesWriteOffsPlan->online_sales_shop_plan; + $write_offs = $salesWriteOffsPlan->write_offs_plan; + ?> + - - + + @@ -236,9 +241,9 @@ input[readonly] { - -
КатегорииПлан продажСписания
ОффлайнИнтернет-МагазинСписания
%Сумма%Cумма%Cумма
'number', 'readonly' => true, ]) ?>
-
+ + + Не задан план по магазину. Чтобы задать план пройдите на страницу diff --git a/erp24/web/js/category-plan/index.js b/erp24/web/js/category-plan/index.js index c7aef7f7..38b02a90 100644 --- a/erp24/web/js/category-plan/index.js +++ b/erp24/web/js/category-plan/index.js @@ -114,17 +114,28 @@ function updateChangesLog(store_id) { changes[store_id] = {}; } console.log(changes); - const count = Object.keys(changes[store_id]).length; + let count = 0; let listItems = ''; Object.entries(changes[store_id]).forEach(([category, values]) => { - if (values.offline !== undefined) + if (values.offline !== undefined) { listItems += `
  • ${category} - ${values.offline}
  • `; - if (values.internet_shop !== undefined) + count++; + } + + if (values.internet_shop !== undefined) { listItems += `
  • ${category} - ${values.internet_shop}
  • `; - if (values.write_offs !== undefined) + count++; + } + + if (values.write_offs !== undefined) { listItems += `
  • ${category} - ${values.write_offs}
  • `; - }); + count++; + } + }); + $('#changes-hint').remove(); + $('#changes').after('
    После внесения всех изменений нажмите на кнопку\n' + + '"Пересчитать автопланограмму"
    '); changesBox.html(``).hide(); changesCount.html(`Были внесены изменения (число изменений) - ${count} `); @@ -148,16 +159,11 @@ $(document).ready(() => { if (store_id && changes[store_id]) { updateChangesLog(store_id); $('#rebuild').prop('disabled', false); - $('#changes-hint').remove(); - $('#changes').after('
    После внесения всех изменений нажмите на кнопку\n' + - '"Пересчитать автопланограмму"
    '); + } $('#delete').on('click', function (event) { event.preventDefault(); - localStorage.removeItem('planChanges'); - - const year = $('#dynamicmodel-year').val(); const month = $('#dynamicmodel-month').val(); const store_id = $('#selected-store').val(); @@ -168,12 +174,18 @@ $(document).ready(() => { 'DynamicModel[store_id]': store_id, 'delete': 1 }; - + $('#rebuild').prop('disabled', true).text('Пересчёт запущен...'); + $('#delete').prop('disabled', true); $.ajax({ - url: '/category-plan/new', + url: '/category-plan/index', method: 'GET', data: params, success: function (response) { + const message = response.message; + console.log(response.data); + alert(`План удалён. ${message} Страница перезагрузится, чтобы пересчитать автоплан`); + localStorage.removeItem('planChanges'); + location.reload(); }, error: function () { alert('Ошибка при удалении автоплана.'); @@ -183,9 +195,9 @@ $(document).ready(() => { $('#rebuild').on('click', function (event) { event.preventDefault(); - localStorage.removeItem('planChanges'); - $('#rebuild').prop('disabled', true).text('Пересчёт запущен...'); + $('#rebuild').prop('disabled', true).text('Пересчёт запущен...'); + $('#delete').prop('disabled', true); $.ajax({ url: '/category-plan/rebuild', type: 'GET', @@ -195,9 +207,16 @@ $(document).ready(() => { store_id: store_id }, success: function (data) { - startTaskPolling(); - $('#rebuild').prop('disabled', true); - console.log(data.data); + if (data.status == 'running') { + alert('Другая задача запущена!'); + return; + } + if (data.status == 'started') { + startTaskPolling(); + $('#rebuild').prop('disabled', true); + console.log(data.data); + } + }, error: function () { alert('Ошибка запуска пересчёта!'); @@ -205,30 +224,46 @@ $(document).ready(() => { } }); }); + startTaskPolling(); }); let taskPollInterval = null; function startTaskPolling() { if (taskPollInterval) return; - + console.log('check-task'); taskPollInterval = setInterval(() => { $.ajax({ url: '/category-plan/check-task', type: 'GET', dataType: 'json', success: function (data) { - if (data.status === 'done' || data.status === 'error') { + console.log(data.status); + if (data.status === 'running' || data.status === 'pending') { + $('#rebuild').prop('disabled', true).text('Пересчёт запущен...'); + $('#delete').prop('disabled', true); + } + if (data.status === 'done') { clearInterval(taskPollInterval); taskPollInterval = null; + localStorage.removeItem('planChanges'); $('#rebuild').prop('disabled', false).text('Пересчитать автопланограмму'); - + $('#delete').prop('disabled', false); if (data.status === 'done') { + $('#changes-hint').remove(); + $('#changes').hide(); alert('Задача успешно завершена'); } else { alert('Задача завершилась с ошибкой: ' + (data.error || '')); } } + if (data.status === 'error') { + clearInterval(taskPollInterval); + taskPollInterval = null; + $('#rebuild').prop('disabled', false).text('Пересчитать автопланограмму'); + $('#delete').prop('disabled', false); + alert('Задача завершилась с ошибкой: ' + (data.error || '')); + } } }); }, 3000);