From c460c31739aceff9a44a3199643395dff2557fab Mon Sep 17 00:00:00 2001 From: Alexander Smirnov Date: Fri, 27 Dec 2024 09:14:43 +0300 Subject: [PATCH] =?utf8?q?[ERP-272]=20=D0=BF=D0=BB=D0=B0=D0=BD=20=D0=BF?= =?utf8?q?=D1=80=D0=BE=D0=B4=D0=B0=D0=B6=20=D0=B8=20=D1=81=D0=BF=D0=B8?= =?utf8?q?=D1=81=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../SalesWriteOffsPlanController.php | 78 ++++++++++++ ...333_create_table_sales_write_offs_plan.php | 36 ++++++ erp24/records/SalesWriteOffsPlan.php | 60 +++++++++ erp24/views/sales-write-offs-plan/index.php | 118 ++++++++++++++++++ erp24/web/js/sales-write-offs-plan/index.js | 68 ++++++++++ 5 files changed, 360 insertions(+) create mode 100644 erp24/controllers/SalesWriteOffsPlanController.php create mode 100755 erp24/migrations/m241225_131333_create_table_sales_write_offs_plan.php create mode 100644 erp24/records/SalesWriteOffsPlan.php create mode 100644 erp24/views/sales-write-offs-plan/index.php create mode 100644 erp24/web/js/sales-write-offs-plan/index.js diff --git a/erp24/controllers/SalesWriteOffsPlanController.php b/erp24/controllers/SalesWriteOffsPlanController.php new file mode 100644 index 00000000..0afdd718 --- /dev/null +++ b/erp24/controllers/SalesWriteOffsPlanController.php @@ -0,0 +1,78 @@ + date('Y'), + 'month' => date('m'), + ], [ + [['year', 'month'], 'safe'] + ]); + + $model->load(Yii::$app->request->get()); + + $prevMonthStart = date("Y-m-01", strtotime("-1 month", strtotime($model->year . "-" . $model->month . "-01"))); + $prevMonthEnd = date("Y-m-t", strtotime("-1 month", strtotime($model->year . "-" . $model->month . "-01"))); + + $years = []; + for ($i = 3; $i >= 0; $i--) { + $year = date("Y") - $i; + $years [$year] = $year; + } + + $stores = CityStore::find()->andWhere(['visible' => '1'])->all(); + $salesWriteOffsPlan = SalesWriteOffsPlan::find()->where(['year' => $model->year, 'month' => $model->month]) + ->indexBy('store_id')->asArray()->all(); + + $sales = Sales::find()->select([ + "sum(CASE WHEN operation='Продажа' THEN summ ELSE (CASE WHEN operation='Возврат' THEN -summ ELSE 0 END) END) as total", + 'store_id']) + ->where(['between', 'date', $prevMonthStart, $prevMonthEnd]) + ->groupBy(['store_id']) + ->indexBy('store_id') + ->asArray()->all(); + + return $this->render('index', compact('model', 'years', 'stores', + 'salesWriteOffsPlan', 'sales')); + } + + public function actionSaveFields() { + $year = Yii::$app->request->post('year'); + $month = Yii::$app->request->post('month'); + $storeId = Yii::$app->request->post('store_id'); + $total_sales_plan = Yii::$app->request->post('total_sales_plan'); +// $total_sales_fact = Yii::$app->request->post('total_sales_fact'); + $write_offs_plan = Yii::$app->request->post('write_offs_plan'); + $offline_sales_plan = Yii::$app->request->post('offline_sales_plan'); + $online_sales_shop_plan = Yii::$app->request->post('online_sales_shop_plan'); + $online_sales_marketplace_plan = Yii::$app->request->post('online_sales_marketplace_plan'); + $salesWriteOffsPlan = SalesWriteOffsPlan::find()->where(['year' => $year, 'month' => $month, 'store_id' => $storeId])->one(); + if (!$salesWriteOffsPlan) { + $salesWriteOffsPlan = new SalesWriteOffsPlan; + $salesWriteOffsPlan->year = $year; + $salesWriteOffsPlan->month = $month; + $salesWriteOffsPlan->store_id = $storeId; + } + $salesWriteOffsPlan->total_sales_plan = $total_sales_plan; + $salesWriteOffsPlan->write_offs_plan = $write_offs_plan; + $salesWriteOffsPlan->offline_sales_plan = $offline_sales_plan; + $salesWriteOffsPlan->online_sales_shop_plan = $online_sales_shop_plan; + $salesWriteOffsPlan->online_sales_marketplace_plan = $online_sales_marketplace_plan; + $salesWriteOffsPlan->save(); + if ($salesWriteOffsPlan->getErrors()) { + throw new \Exception(Json::encode($salesWriteOffsPlan->getErrors())); + } + return 'ok'; + } +} diff --git a/erp24/migrations/m241225_131333_create_table_sales_write_offs_plan.php b/erp24/migrations/m241225_131333_create_table_sales_write_offs_plan.php new file mode 100755 index 00000000..6d05f5f8 --- /dev/null +++ b/erp24/migrations/m241225_131333_create_table_sales_write_offs_plan.php @@ -0,0 +1,36 @@ +createTable(self::TABLE_NAME, [ + 'id' => $this->primaryKey(), + 'year' => $this->integer()->notNull()->comment('Год создания отчёта'), + 'month' => $this->integer()->notNull()->comment('Месяц создания отчёта'), + 'store_id' => $this->integer()->notNull()->comment('id магазина в ERP'), + 'total_sales_plan' => $this->float()->null()->comment('План продаж'), + 'write_offs_plan' => $this->float()->null()->comment('План списания'), + 'offline_sales_plan' => $this->float()->null()->comment('План продаж офлайн'), + 'online_sales_shop_plan' => $this->float()->null()->comment('План online продаж магазина'), + 'online_sales_marketplace_plan' => $this->float()->null()->comment('План online продаж маркетплейса'), + ]); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropTable(self::TABLE_NAME); + } +} diff --git a/erp24/records/SalesWriteOffsPlan.php b/erp24/records/SalesWriteOffsPlan.php new file mode 100644 index 00000000..a48c94d6 --- /dev/null +++ b/erp24/records/SalesWriteOffsPlan.php @@ -0,0 +1,60 @@ + null], + [['year', 'month', 'store_id'], 'integer'], + [['total_sales_plan', 'write_offs_plan', 'offline_sales_plan', 'online_sales_shop_plan', 'online_sales_marketplace_plan'], 'number'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'year' => 'Year', + 'month' => 'Month', + 'store_id' => 'Store ID', + 'total_sales_plan' => 'Total Sales Plan', + 'write_offs_plan' => 'Write Offs Plan', + 'offline_sales_plan' => 'Offline Sales Plan', + 'online_sales_shop_plan' => 'Online Sales Shop Plan', + 'online_sales_marketplace_plan' => 'Online Sales Marketplace Plan', + ]; + } +} diff --git a/erp24/views/sales-write-offs-plan/index.php b/erp24/views/sales-write-offs-plan/index.php new file mode 100644 index 00000000..76cca00a --- /dev/null +++ b/erp24/views/sales-write-offs-plan/index.php @@ -0,0 +1,118 @@ +registerJsFile('/js/sales-write-offs-plan/index.js', ['position' => \yii\web\View::POS_END]); + +function colorScheme1($p) { + $p = round(100 * $p); + if ($p <= 90) { return 'red'; } + if ($p < 99) { return '#aaaa00'; } + return 'green'; +} + +function colorScheme2($p) { + $p = round(100 * $p, 1); + if ($p > 10) { return 'red'; } + if ($p > 9) { return '#aaaa00'; } + return 'green'; +} + +?> + +
+ + 'GET', + 'action' => '/sales-write-offs-plan' + ]) ?> + +
+
+ field($model, 'year')->dropDownList($years, ['onchange' => 'this.form.submit();'])->label(false) ?> +
+
+
+
+ field($model, 'month')->dropDownList(HtmlHelper::getMonthNames(), ['onchange' => 'this.form.submit();'])->label(false) ?> +
+
+ + + + + + + + + + + + id]['total'] ?? 0; + $total_sales_plan = $salesWriteOffsPlan[$store->id]['total_sales_plan'] ?? 0; + $p1 = $total_sales_fact > 0 ? $total_sales_plan / $total_sales_fact : 0; + + $write_offs_plan = $salesWriteOffsPlan[$store->id]['write_offs_plan'] ?? 0; + $p2 = $total_sales_plan > 0 ? $write_offs_plan / $total_sales_plan : 0; + + $offline_sales_plan = $salesWriteOffsPlan[$store->id]['offline_sales_plan'] ?? 0; + $p3 = $total_sales_fact > 0 ? $offline_sales_plan / $total_sales_fact : 0; + + $online_sales_shop_plan = $salesWriteOffsPlan[$store->id]['online_sales_shop_plan'] ?? 0; + $p4 = $total_sales_fact > 0 ? $online_sales_shop_plan / $total_sales_fact : 0; + + $online_sales_marketplace_plan = $salesWriteOffsPlan[$store->id]['online_sales_marketplace_plan'] ?? 0; + $p5 = $total_sales_fact > 0 ? $online_sales_marketplace_plan / $total_sales_fact : 0; + ?> + + + + + + + + + + + + + + + +
МагазиныTotalОффлайн торговляОнлайн торговля
Оффлайн + онлайн торговляМагазинИнтернет-магазинМаркетплейсы
ПродажиК прошлому месяцуСписанияК ПлануЦельК прошлому месяцуЦельК прошлому месяцуЦельК прошлому месяцу
name ?>id) ?> 'number', 'readonly' => true]) ?> + + + + % + 'number', 'onchange' => 'editField(this);']) ?> + + + % + 'number', 'onchange' => 'editField(this);']) ?> + + + % + 'number', 'onchange' => 'editField(this);']) ?> + + + % + 'number', 'onchange' => 'editField(this);']) ?> + + + % +
+
diff --git a/erp24/web/js/sales-write-offs-plan/index.js b/erp24/web/js/sales-write-offs-plan/index.js new file mode 100644 index 00000000..3296989c --- /dev/null +++ b/erp24/web/js/sales-write-offs-plan/index.js @@ -0,0 +1,68 @@ +/* jshint esversion: 6 */ + +const param25 = $('meta[name=csrf-param]').attr('content'); +const token25 = $('meta[name=csrf-token]').attr('content'); + +function isNumeric(value) { + return /^-?\d+\.?\d*$/.test(value); +} + +function editField(zis) { + const tr = zis.parentNode.parentNode; + const store_id = tr.querySelector("[name=store_id]").value; + const total_sales_plan = tr.querySelector("[name=total_sales_plan]"); + const total_sales_fact = tr.querySelector("[name=total_sales_fact]"); + const write_offs_plan = tr.querySelector("[name=write_offs_plan]"); + const offline_sales_plan = tr.querySelector("[name=offline_sales_plan]"); + const online_sales_shop_plan = tr.querySelector("[name=online_sales_shop_plan]"); + const online_sales_marketplace_plan = tr.querySelector("[name=online_sales_marketplace_plan]"); + const editFields = [ + total_sales_plan, + total_sales_fact, + write_offs_plan, + offline_sales_plan, + online_sales_shop_plan, + online_sales_marketplace_plan, + ]; + let succ = true; + editFields.forEach((el) => { + if (!isNumeric(el.value)) { + succ = false; + alert(el.value); + console.log(el); + } + }); + if (succ) { + total_sales_plan.value = +offline_sales_plan.value + (+online_sales_shop_plan.value) + (+online_sales_marketplace_plan.value); + $.ajax({ + method: "POST", + url: '/sales-write-offs-plan/save-fields', + data: { + year: document.querySelector('#dynamicmodel-year').value, + month: document.querySelector('#dynamicmodel-month').value, + store_id, + total_sales_plan : total_sales_plan.value, + total_sales_fact : total_sales_fact.value, + write_offs_plan : write_offs_plan.value, + offline_sales_plan : offline_sales_plan.value, + online_sales_shop_plan : online_sales_shop_plan.value, + online_sales_marketplace_plan : online_sales_marketplace_plan.value, + [param25]: token25 + }, + dataType: "text", + success: function(data) { + console.log(data); + }, + }); + } +} + +$(document).ready(() => { + $('#storePlans').DataTable({ + sorting: false, + info: false, + paging: false, + searching: true, + language: data_table_language + }); +}); -- 2.39.5