Commit 42078ac69f543f844040a491f33ea2d0509569a5

Authored by Mihail
1 parent 2d5bfb36

add manual insert func to margin grup model

backend/controllers/RgGrupController.php
... ... @@ -20,7 +20,8 @@ use yii\data\ArrayDataProvider;
20 20 use yii\multiparser\DynamicFormHelper;
21 21 use common\components\CustomArrayHelper;
22 22  
23   -class RgGrupController extends BaseController {
  23 +class RgGrupController extends BaseController
  24 +{
24 25 public $layout = "/column";
25 26  
26 27 /**
... ... @@ -79,9 +80,9 @@ class RgGrupController extends BaseController {
79 80 // не прошла валидация форма загрузки файлов
80 81 $errors_str = '';
81 82 foreach ($model->getErrors() as $error) {
82   - $errors_str .= implode( array_values($error) );
  83 + $errors_str .= implode(array_values($error));
83 84 }
84   - throw new \ErrorException( $errors_str );
  85 + throw new \ErrorException($errors_str);
85 86 }
86 87 // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
87 88 } else if (Yii::$app->getCache()->get('parser_data')) {
... ... @@ -95,11 +96,10 @@ class RgGrupController extends BaseController {
95 96 'pageSize' => 10,
96 97 ],
97 98 ]);
98   -
99 99 // создадим модель на столько реквизитов сколько колонок в отпарсенном файле
100   - $last_index = end( array_flip( $data[0] ) );
  100 + $last_index = end(array_flip($data[0]));
101 101 $header_counts = $last_index + 1;
102   - $header_model = DynamicFormHelper::CreateDynamicModel( $header_counts );
  102 + $header_model = DynamicFormHelper::CreateDynamicModel($header_counts);
103 103  
104 104 // соберем массив данных из которых будет пользователь выбирать значения в конструкторе (выпадающий список)
105 105 $header_array = Margins::getHeader();
... ... @@ -137,18 +137,18 @@ class RgGrupController extends BaseController {
137 137 throw new \ErrorException('Ошибка кеша');
138 138 }
139 139  
140   - array_walk($arr, function(&$val){
141   - $val = '!'.$val;
  140 + array_walk($arr, function (&$val) {
  141 + $val = '!' . $val;
142 142 });
143 143  
144 144 // соотнесем отпарсенные данные с соответсивем полученным от пользователя
145 145 // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
146   - $data = CustomArrayHelper::createAssocArray( $data, $arr , 'attr_' );
  146 + $data = CustomArrayHelper::createAssocArray($data, $arr, 'attr_');
147 147  
148 148 // в первой строке у нас заголовки - уберем
149 149 unset($data[0]);
150 150 // подготовим данные для записи в таблицу w_margins_groups
151   - //$arr_values = [];
  151 + $arr_values = [];
152 152 $group = '';
153 153 $importer_id = $configuration['importer_id'];
154 154 foreach ($data as $row_data) {
... ... @@ -162,39 +162,32 @@ class RgGrupController extends BaseController {
162 162 }
163 163  
164 164 foreach ($row_data as $key => $value) {
165   - if($group)
166   - $row['group'] = trim( $group );
167   -
168   - $row['importer_id'] = trim( $importer_id );
169   - $row['margin_id'] = ltrim($key,'!');
170   - $row['koef'] = \Yii::$app->converter->convertTo( 'float', $value );
171   -
172   - // сохраним подготовленные данные
173   - $margins_groups = new MarginsGroups();
174   - $margins_groups->attributes = $row;
175   -
176   - if ( !$margins_groups->save() ) {
177   - $errors_str = '';
178   - foreach ($margins_groups->getErrors() as $error) {
179   - $errors_str .= implode( array_values($error) );
180   - }
181   - throw new \ErrorException( $errors_str );
  165 + if ($group)
  166 + $row['group'] = trim($group);
  167 +
  168 + $row['importer_id'] = trim($importer_id);
  169 + $row['margin_id'] = ltrim($key, '!');
  170 + $row['koef'] = \Yii::$app->converter->convertTo('float', $value);
  171 +
  172 + $arr_values[] = $row;
  173 +
182 174 }
183   - }
184 175  
185   - Yii::$app->session->setFlash('success');
186   - // все прошло успешно - очищаем кеш
187   - Yii::$app->getCache()->delete('parser_data');
188   - Yii::$app->getCache()->delete('parser_configuration');
  176 + }
  177 + // сохраним подготовленные данные
  178 + MarginsGroups::ManualInsertWithUpdate( $arr_values, [ 'group','importer_id','margin_id' ] );
189 179  
190   - if( file_exists($configuration['file_path']) )
191   - unlink($configuration['file_path']);
192 180  
193   - return $this->render('index', ['model' => $configuration]);
  181 + Yii::$app->session->setFlash('success', "Файл {$configuration['file']} успешно загружен");
  182 + // все прошло успешно - очищаем кеш
  183 + Yii::$app->getCache()->delete('parser_data');
  184 + Yii::$app->getCache()->delete('parser_configuration');
194 185  
  186 + if (file_exists($configuration['file_path']))
  187 + unlink($configuration['file_path']);
195 188  
  189 + return $this->render('index', ['model' => $configuration]);
196 190  
197   - }
198 191  
199 192 }
200 193  
... ...
common/models/MarginsGroups.php
... ... @@ -74,4 +74,42 @@ class MarginsGroups extends \yii\db\ActiveRecord
74 74 {
75 75 return $this->hasOne(Margins::className(), ['id' => 'margin_id']);
76 76 }
  77 +
  78 + /**
  79 + * вставка данных с апдейтом прямым запросом SQL
  80 + * @param $data - массив вставляемых данный, вставка будет прозводится пакетами размером указанным в константе BATCH
  81 + * @throws \yii\db\Exception
  82 + */
  83 + //@todo - вынести все ручные инсерты в отдельный класс
  84 + public static function ManualInsertWithUpdate($data, $keys)
  85 + {
  86 + // \common\components\CustomVarDamp::dumpAndDie($data);
  87 + $table_name = self::tableName();
  88 + $keys_arr = array_keys($data[0]);
  89 + // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить
  90 + $fields_arr_to_update = array_diff( $keys_arr, $keys );
  91 +
  92 + $query_update = ' on duplicate key update ';
  93 + foreach ($fields_arr_to_update as $field) {
  94 + $query_update .= "[[{$field}]] = values([[{$field}]]),";
  95 + }
  96 + // удалим последнюю запятую
  97 + $query_update = substr($query_update, 0, strlen($query_update) - 1);
  98 +
  99 + // запросы будем выполнять пакетами
  100 + // размер пакета установлен в константе
  101 + // разобъем массив на пакеты и будем их проходить
  102 + $data = array_chunk($data, 20);
  103 + foreach ($data as $current_batch_array) {
  104 +
  105 + //воспользуемся пакетной вставкой от фреймворка
  106 + $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql;
  107 +
  108 + // добавим фрагмент с апдейтом при дубляже
  109 + $query = "{$query_insert} {$query_update}";
  110 + // \common\components\CustomVarDamp::dumpAndDie($query);
  111 + Yii::$app->db->createCommand($query)->execute();
  112 +
  113 + }
  114 + }
77 115 }
... ...