use yii\web\UploadedFile;
use yii_app\records\CityStore;
use yii_app\records\MotivationCostsItem;
+use yii_app\services\MotivationService;
class IndexAction extends Action
{
$path = Yii::getAlias('@uploads') . '/template_plan.xslx';
$file->saveAs($path);
- $motivationCostsItems = MotivationCostsItem::find()->indexBy('code')->all();
- $spreadsheets = IOFactory::load($path);
- $sheets = [];
- $errors = [];
- foreach ($spreadsheets->getAllSheets() as $spreadSheet) {
- $rows = [];
- $finish = false;
- $storeStr = true;
- $error = '';
- foreach ($spreadSheet->getRowIterator() as $ind => $spreadSheetRow) {
- $row = [];
- foreach ($spreadSheetRow->getCellIterator() as $spreadSheetRowCell) {
- $value = $spreadSheetRowCell->getValue();
- if ($value == '###') {
- $finish = true;
- break;
- }
- $row []= $value;
- }
- if ($finish) {
- break;
- }
- if ($storeStr) {
- $store = CityStore::find()->where(['id' => $row[0] ?? -1])->one();
- if (!$store) {
- $error = "Не найден магазин с таким индексом [0,0]";
- break;
- } elseif ($store->name != ($row[1] ?? 'NO_NAME')) {
- $error = "Не найден магазин с таким названием [1,0]" . $row[1] . ' ' . $store->name;
- break;
- }
- $year = ((int)$row[2]) ?? -1;
- $month = ((int)$row[3]) ?? -1;
- if ($year > 2030 || $year < 2023) {
- $error = "Не корректно указан год [2,0]";
- break;
- }
- if ($month < 1 || $month > 12) {
- $error = "Не корректно указан месяц [3,0]";
- break;
- }
- $storeStr = false;
- } else {
- if (!isset($motivationCostsItems[$row[0] ?? -1])) {
- $error = "Не корректен код элемента " . ($row[0] ?? '') . "[$ind,0]";
- break;
- }
- /** @var $motivationCostsItems MotivationCostsItem[] */
- if ($motivationCostsItems[$row[0]]->name != ($row[1] ?? 'NO_NAME')) {
- $error = "Не корректно название элемента " . ($row[1] ?? '') . "[$ind,1]";
- break;
- }
- if (($row[2] ?? 'NO_NAME') == 'NO_NAME') {
- $error = "Не корректно значение элемента [$ind,2]";
- break;
- }
- switch ($motivationCostsItems[$row[0]]->data_type) {
- case MotivationCostsItem::DATA_TYPE_INT: { if (is_int($row[2])) { $value = (int)$row[2]; } else { $error = "Не инт [$ind,2]"; }; break; }
- case MotivationCostsItem::DATA_TYPE_FLOAT: { if (is_int($row[2]) || is_float($row[2])) { $value = (float)$row[2]; } else {$error = "Не флот [$ind,2]"; } break; }
- case MotivationCostsItem::DATA_TYPE_STRING: { $value = $row[2]; break; }
- }
- if (!empty($error)) {
- break;
- }
- }
- $rows []= $row;
- }
- $errors []= empty($error) ? '' : $error;
- $sheets []= $rows;
- }
+ $data = MotivationService::uploadTemplatePlan($path);
- return implode('<br>', $errors);
+ return implode('<br>', $data['errors']);
} else {
return 'not ok';
}
--- /dev/null
+<?php
+
+namespace yii_app\records;
+
+use Yii;
+
+/**
+ * This is the model class for table "motivation".
+ *
+ * @property int $id
+ * @property int $store_id ID магазина
+ * @property int $year Год
+ * @property int $month Месяц
+ * @property string $updated_at Дата изменения записи
+ * @property string $created_at Дата создания записи
+ */
+class Motivation extends \yii\db\ActiveRecord
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function tableName()
+ {
+ return 'motivation';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rules()
+ {
+ return [
+ [['store_id', 'year', 'month', 'updated_at', 'created_at'], 'required'],
+ [['store_id', 'year', 'month'], 'default', 'value' => null],
+ [['store_id', 'year', 'month'], 'integer'],
+ [['updated_at', 'created_at'], 'safe'],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'store_id' => 'Store ID',
+ 'year' => 'Year',
+ 'month' => 'Month',
+ 'updated_at' => 'Updated At',
+ 'created_at' => 'Created At',
+ ];
+ }
+}
--- /dev/null
+<?php
+
+namespace yii_app\records;
+
+use Yii;
+
+/**
+ * This is the model class for table "motivation_value".
+ *
+ * @property int $id
+ * @property int $motivation_id ID motivation
+ * @property int $motivation_group_id ID motivation
+ * @property int $value_id ID motivation
+ * @property string $value_type тип значения
+ * @property int|null $value_int value int
+ * @property float|null $value_float value float
+ * @property string|null $value_string value string
+ */
+class MotivationValue extends \yii\db\ActiveRecord
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function tableName()
+ {
+ return 'motivation_value';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rules()
+ {
+ return [
+ [['motivation_id', 'motivation_group_id', 'value_id', 'value_type'], 'required'],
+ [['motivation_id', 'motivation_group_id', 'value_id', 'value_int'], 'default', 'value' => null],
+ [['motivation_id', 'motivation_group_id', 'value_id', 'value_int'], 'integer'],
+ [['value_float'], 'number'],
+ [['value_type'], 'string', 'max' => 10],
+ [['value_string'], 'string', 'max' => 255],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'motivation_id' => 'Motivation ID',
+ 'motivation_group_id' => 'Motivation Group ID',
+ 'value_id' => 'Value ID',
+ 'value_type' => 'Value Type',
+ 'value_int' => 'Value Int',
+ 'value_float' => 'Value Float',
+ 'value_string' => 'Value String',
+ ];
+ }
+}
--- /dev/null
+<?php
+
+namespace yii_app\records;
+
+use Yii;
+
+/**
+ * This is the model class for table "motivation_value_group".
+ *
+ * @property int $id
+ * @property string $name Название
+ * @property string $alias Алиас
+ */
+class MotivationValueGroup extends \yii\db\ActiveRecord
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function tableName()
+ {
+ return 'motivation_value_group';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rules()
+ {
+ return [
+ [['name', 'alias'], 'required'],
+ [['name', 'alias'], 'string', 'max' => 80],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'name' => 'Name',
+ 'alias' => 'Alias',
+ ];
+ }
+}
--- /dev/null
+<?php
+
+namespace yii_app\services;
+
+use PhpOffice\PhpSpreadsheet\IOFactory;
+use yii_app\records\Motivation;
+use yii_app\records\MotivationValue;
+use yii_app\records\MotivationValueGroup;
+use yii_app\records\CityStore;
+use yii_app\records\MotivationCostsItem;
+
+class MotivationService
+{
+ public static function uploadTemplatePlan($path) {
+ $motivationCostsItems = MotivationCostsItem::find()->indexBy('code')->all();
+ $spreadsheets = IOFactory::load($path);
+ $errors = [];
+ foreach ($spreadsheets->getAllSheets() as $spreadSheet) {
+ $rows = [];
+ $finish = false;
+ $storeStr = true;
+ $error = '';
+ $motivation = null;
+ foreach ($spreadSheet->getRowIterator() as $ind => $spreadSheetRow) {
+ $row = [];
+ foreach ($spreadSheetRow->getCellIterator() as $spreadSheetRowCell) {
+ $value = $spreadSheetRowCell->getValue();
+ if ($value == '###') {
+ $finish = true;
+ break;
+ }
+ $row []= $value;
+ }
+ if ($finish) {
+ break;
+ }
+ if ($storeStr) {
+ $store = CityStore::find()->where(['id' => $row[0] ?? -1])->one();
+ if (!$store) {
+ $error = "Не найден магазин с таким индексом [0,0]";
+ break;
+ } elseif ($store->name != ($row[1] ?? 'NO_NAME')) {
+ $error = "Не найден магазин с таким названием [1,0]" . $row[1] . ' ' . $store->name;
+ break;
+ }
+ $year = ((int)$row[2]) ?? -1;
+ $month = ((int)$row[3]) ?? -1;
+ if ($year > 2030 || $year < 2023) {
+ $error = "Не корректно указан год [2,0]";
+ break;
+ }
+ if ($month < 1 || $month > 12) {
+ $error = "Не корректно указан месяц [3,0]";
+ break;
+ }
+
+ $motivation = Motivation::find()->where(['store_id' => $store->id, 'year' => $year, 'month' => $month])->one();
+ /** @var $motivation Motivation */
+ if ($motivation) {
+ $motivation->updated_at = date('Y-m-d H:i:s');
+ } else {
+ $motivation = new Motivation;
+ $motivation->store_id = $store->id;
+ $motivation->year = $year;
+ $motivation->month = $month;
+ $motivation->created_at = date('Y-m-d H:i:s');
+ $motivation->updated_at = date('Y-m-d H:i:s');
+ }
+
+ $storeStr = false;
+ } else {
+ if (!isset($motivationCostsItems[$row[0] ?? -1])) {
+ $error = "Не корректен код элемента " . ($row[0] ?? '') . "[$ind,0]";
+ break;
+ }
+ /** @var $motivationCostsItems MotivationCostsItem[] */
+ if ($motivationCostsItems[$row[0]]->name != ($row[1] ?? 'NO_NAME')) {
+ $error = "Не корректно название элемента " . ($row[1] ?? '') . "[$ind,1]";
+ break;
+ }
+ if (($row[2] ?? 'NO_NAME') == 'NO_NAME') {
+ $error = "Не корректно значение элемента [$ind,2]";
+ break;
+ }
+ switch ($motivationCostsItems[$row[0]]->data_type) {
+ case MotivationCostsItem::DATA_TYPE_INT: { if (is_int($row[2])) { $value = (int)$row[2]; } else { $error = "Не инт [$ind,2]"; }; break; }
+ case MotivationCostsItem::DATA_TYPE_FLOAT: { if (is_int($row[2]) || is_float($row[2])) { $value = (float)$row[2]; } else {$error = "Не флот [$ind,2]"; } break; }
+ case MotivationCostsItem::DATA_TYPE_STRING: { $value = $row[2]; break; }
+ }
+ if (!empty($error)) {
+ break;
+ }
+ }
+ $rows []= $row;
+ }
+ if ($motivation && empty($error)) {
+ $motivation->save();
+ if ($motivation->getErrors()) {
+ $error = json_encode($motivation->getErrors());
+ }
+ } else {
+ $error = 'Не указан магазин, год и месяц [0,0]';
+ }
+ if (empty($error)) {
+ $motivationValueGroupPlan = MotivationValueGroup::find()->where(['alias' => 'plan'])->one();
+ /** @var $motivationValueGroupPlan MotivationValueGroup */
+ foreach ($rows as $row) {
+ $motivationValue = MotivationValue::find()->where([
+ 'motivation_id' => $motivation->id,
+ 'motivation_group_id' => $motivationValueGroupPlan->id,
+ 'value_id' => $row[0]
+ ])->one();
+ /** @var $motivationValue MotivationValue */
+ if (!$motivationValue) {
+ $motivationValue = new MotivationValue;
+ $motivationValue->motivation_id = $motivation->id;
+ $motivationValue->motivation_group_id = $motivationValueGroupPlan->id;
+ $motivationValue->value_id = $row[0];
+ }
+ $motivationValue->value_type = $motivationCostsItems[$row[0]]->data_type;
+ switch ($motivationValue->value_type) {
+ case MotivationCostsItem::DATA_TYPE_INT: { $motivationValue->value_int = (int)$row[2]; break; }
+ case MotivationCostsItem::DATA_TYPE_FLOAT: { $motivationValue->value_float = (float)$row[2]; break; }
+ case MotivationCostsItem::DATA_TYPE_STRING: { $motivationValue->value_string = '' . $row[2]; break; }
+ }
+ $motivationValue->save();
+ if ($motivationValue->getErrors()) {
+ $error = json_encode($motivationValue->getErrors());
+ break;
+ }
+ }
+ }
+ $errors []= empty($error) ? '' : $error;
+ }
+
+ return compact('errors');
+ }
+}
\ No newline at end of file