Commit 40cac1b611a0d7f946e42d308f4591e518045cfb

Authored by Mihail
1 parent 7ee738d0

add delete func in deteils model

backend/controllers/ParserController.php
@@ -101,7 +101,6 @@ class ParserController extends BaseController @@ -101,7 +101,6 @@ class ParserController extends BaseController
101 } 101 }
102 102
103 $model->file->saveAs($model->file_path); 103 $model->file->saveAs($model->file_path);
104 -  
105 // для авто загрузки, обработка завершена 104 // для авто загрузки, обработка завершена
106 if ($model->mode) { 105 if ($model->mode) {
107 $model->success = true; 106 $model->success = true;
@@ -124,12 +123,11 @@ class ParserController extends BaseController @@ -124,12 +123,11 @@ class ParserController extends BaseController
124 123
125 } else { 124 } else {
126 // не прошла валидация форма загрузки файлов 125 // не прошла валидация форма загрузки файлов
127 - //@todo - отправка на страницу ошибок  
128 - $errors_arr = $model->getErrors();  
129 - foreach ($errors_arr as $error) {  
130 - CustomVarDamp::dump(array_values($error)); 126 + $errors_str = '';
  127 + foreach ($model->getErrors() as $error) {
  128 + $errors_str .= implode( array_values($error) );
131 } 129 }
132 - die; 130 + throw new ErrorException( $errors_str );
133 } 131 }
134 // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные 132 // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
135 } else if (Yii::$app->getCache()->get('parser_data')) { 133 } else if (Yii::$app->getCache()->get('parser_data')) {
@@ -145,8 +143,11 @@ class ParserController extends BaseController @@ -145,8 +143,11 @@ class ParserController extends BaseController
145 ], 143 ],
146 ]); 144 ]);
147 145
  146 +
  147 + $last_index = end( array_flip( $data[0] ) );
  148 + $header_counts = $last_index + 1;
148 //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список) 149 //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список)
149 - $header_model = DynamicFormHelper::CreateDynamicModel(count($data[0])); 150 + $header_model = DynamicFormHelper::CreateDynamicModel( $header_counts );
150 151
151 return $this->render('results', 152 return $this->render('results',
152 ['model' => $data, 153 ['model' => $data,
backend/models/Details.php
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 namespace backend\models; 3 namespace backend\models;
4 4
  5 +use common\components\CustomVarDamp;
5 use Yii; 6 use Yii;
6 use backend\components\base\BaseActiveRecord; 7 use backend\components\base\BaseActiveRecord;
7 8
@@ -22,8 +23,22 @@ use backend\components\base\BaseActiveRecord; @@ -22,8 +23,22 @@ use backend\components\base\BaseActiveRecord;
22 */ 23 */
23 class Details extends BaseActiveRecord 24 class Details extends BaseActiveRecord
24 { 25 {
25 - const KEY_COLUMN = ['IMPORT_ID','BRAND','ARTICLE']; 26 + /**
  27 + *обязательные колонки
  28 + */
  29 + const KEY_COLUMN = ['IMPORT_ID', 'BRAND', 'ARTICLE'];
  30 +
  31 + /**
  32 + * int - размер пакета запроса
  33 + */
26 const BATCH = 500; 34 const BATCH = 500;
  35 +
  36 + /**
  37 + * @var bool - признак необходимости удалить префикс Артикула перед вставкой
  38 + */
  39 + public $delete_prefix = false;
  40 + public $delete_price = false;
  41 +
27 /** 42 /**
28 * @inheritdoc 43 * @inheritdoc
29 */ 44 */
@@ -38,8 +53,8 @@ class Details extends BaseActiveRecord @@ -38,8 +53,8 @@ class Details extends BaseActiveRecord
38 public function rules() 53 public function rules()
39 { 54 {
40 return [ 55 return [
41 - [[ 'BRAND', 'ARTICLE', 'PRICE', 'DESCR', 'BOX'], 'required'],  
42 - // [['IMPORT_ID', 'BOX', 'ADD_BOX'], 'integer'], 56 + [['BRAND', 'ARTICLE', 'PRICE', 'DESCR', 'BOX'], 'required'],
  57 + // [['IMPORT_ID', 'BOX', 'ADD_BOX'], 'integer'],
43 [['PRICE'], 'number'], 58 [['PRICE'], 'number'],
44 [['BOX'], 'integer'], 59 [['BOX'], 'integer'],
45 [['timestamp'], 'safe'], 60 [['timestamp'], 'safe'],
@@ -69,13 +84,38 @@ class Details extends BaseActiveRecord @@ -69,13 +84,38 @@ class Details extends BaseActiveRecord
69 ]; 84 ];
70 } 85 }
71 86
72 - public function ManualInsert ($data) 87 + /**
  88 + *удаление (если $delete_price установлен)б а затем вставка данных с апдейтом прямымыми запросоми SQL
  89 + * @param $data - массив вставляемых данных, вставка будет прозводится пакетами размером указанным в константе BATCH
  90 + * @param $importer_id - (int) - идентификатор поставщика у которого будет сперва удалены прайсы а потом вставлены из массива $data
  91 + * @throws \yii\db\Exception
  92 + */
  93 + public function ManualInsert($data, $importer_id)
  94 + {
  95 + if ($this->delete_price) {
  96 + // запустим пакетное удаление всех прайсов поставщика
  97 + do {
  98 + $query = Yii::$app->db->createCommand()->delete(self::tableName(), "IMPORT_ID = {$importer_id}")->sql . ' Limit ' . $this::BATCH;
  99 + $res = Yii::$app->db->createCommand($query)->execute();
  100 + } while ($res);
  101 +
  102 + }
  103 +
  104 + $this->ManualInsertWithUpdate($data);
  105 + }
  106 +
  107 + /**
  108 + * вставка данных с апдейтом прямым запросом SQL
  109 + * @param $data - массив вставляемых данный, вставка будет прозводится пакетами размером указанным в константе BATCH
  110 + * @throws \yii\db\Exception
  111 + */
  112 + private function ManualInsertWithUpdate($data)
73 { 113 {
74 // \common\components\CustomVarDamp::dumpAndDie($data); 114 // \common\components\CustomVarDamp::dumpAndDie($data);
75 $table_name = self::tableName(); 115 $table_name = self::tableName();
76 - $keys_arr = array_keys( $data[0] ); 116 + $keys_arr = array_keys($data[0]);
77 // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить 117 // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить
78 - $fields_arr_to_update = array_diff( $keys_arr, $this::KEY_COLUMN ); 118 + $fields_arr_to_update = array_diff($keys_arr, $this::KEY_COLUMN);
79 119
80 $query_update = ' on duplicate key update '; 120 $query_update = ' on duplicate key update ';
81 foreach ($fields_arr_to_update as $field) { 121 foreach ($fields_arr_to_update as $field) {
@@ -87,8 +127,8 @@ class Details extends BaseActiveRecord @@ -87,8 +127,8 @@ class Details extends BaseActiveRecord
87 // запросы будем выполнять пакетами 127 // запросы будем выполнять пакетами
88 // размер пакета установлен в константе 128 // размер пакета установлен в константе
89 // разобъем массив на пакеты и будем их проходить 129 // разобъем массив на пакеты и будем их проходить
90 - $data = array_chunk($data, $this::BATCH );  
91 - foreach( $data as $current_batch_array ){ 130 + $data = array_chunk($data, $this::BATCH);
  131 + foreach ($data as $current_batch_array) {
92 132
93 //воспользуемся пакетной вставкой от фреймворка, плюс сразу с экранированием и защитой от инъекций 133 //воспользуемся пакетной вставкой от фреймворка, плюс сразу с экранированием и защитой от инъекций
94 $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql; 134 $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql;
@@ -100,5 +140,4 @@ class Details extends BaseActiveRecord @@ -100,5 +140,4 @@ class Details extends BaseActiveRecord
100 } 140 }
101 } 141 }
102 142
103 -  
104 } 143 }
backend/models/UploadFileParsingForm.php
@@ -77,7 +77,9 @@ class UploadFileParsingForm extends Model @@ -77,7 +77,9 @@ class UploadFileParsingForm extends Model
77 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}"); 77 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}");
78 } 78 }
79 // файл больше не нужен - данные прочитаны и сохранены в кеш 79 // файл больше не нужен - данные прочитаны и сохранены в кеш
80 - unlink($this->file_path); 80 + if( file_exists($this->file_path) )
  81 + unlink($this->file_path);
  82 +
81 return $data; 83 return $data;
82 } 84 }
83 85
common/components/PriceWriter.php
@@ -14,22 +14,45 @@ use backend\models\ImportersFiles; @@ -14,22 +14,45 @@ use backend\models\ImportersFiles;
14 use backend\models\Importers; 14 use backend\models\Importers;
15 use backend\models\Details; 15 use backend\models\Details;
16 16
17 -class PriceWriter { 17 +/**
  18 + * Class PriceWriter
  19 + * @package common\components
  20 + * записывает в БД отпарсенные данные
  21 + * запись происходит в несколько таблиц
  22 + */
  23 +class PriceWriter
  24 +{
  25 + /**
  26 + * @var - int - 0 - интерактивный режим, 1 - консольный
  27 + */
18 public $mode; 28 public $mode;
  29 +
  30 + /**
  31 + * @var - массив с настройками записи
  32 + */
19 public $configuration; 33 public $configuration;
  34 +
  35 + /**
  36 + * @var - массив с данными которые нужно записать
  37 + */
20 public $data; 38 public $data;
21 39
22 - public function writeDataToDB () 40 + function __construct()
  41 + {
  42 + set_time_limit(300);
  43 + }
  44 +
  45 + public function writeDataToDB()
23 { 46 {
24 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles) 47 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles)
25 // id загруженного файла получим из конфигурации 48 // id загруженного файла получим из конфигурации
26 - $files_model = ImportersFiles::findOne( $this->configuration['record_id'] ); 49 + $files_model = ImportersFiles::findOne($this->configuration['record_id']);
27 50
28 $update_date = date('Y-m-d H:i:s'); 51 $update_date = date('Y-m-d H:i:s');
29 $files_model->time_start = $update_date; 52 $files_model->time_start = $update_date;
30 // запишем дату начала загрузки 53 // запишем дату начала загрузки
31 if (!$files_model->save()) { 54 if (!$files_model->save()) {
32 - throw new \ErrorException(implode( ', ', $files_model->getErrors())); 55 + throw new \ErrorException(implode(', ', $files_model->getErrors()));
33 } 56 }
34 57
35 // 2. запишем полученные данные в таблицу товаров (Details) 58 // 2. запишем полученные данные в таблицу товаров (Details)
@@ -43,7 +66,7 @@ class PriceWriter { @@ -43,7 +66,7 @@ class PriceWriter {
43 $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']); 66 $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']);
44 // присвоим полный артикул 67 // присвоим полный артикул
45 $row['FULL_ARTICLE'] = $row['ARTICLE']; 68 $row['FULL_ARTICLE'] = $row['ARTICLE'];
46 - if(isset($row['ADD_BOX'])) 69 + if (isset($row['ADD_BOX']))
47 $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']); 70 $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']);
48 71
49 // проверим все ли обязательные колонки были указаны пользователем 72 // проверим все ли обязательные колонки были указаны пользователем
@@ -55,31 +78,35 @@ class PriceWriter { @@ -55,31 +78,35 @@ class PriceWriter {
55 } 78 }
56 } 79 }
57 80
58 - // дополним данные значением импортера и даты обновления цены  
59 - $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); 81 + // дополним данные значением импортера и даты обновления цены
  82 + $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]);
  83 + try {
  84 + //@todo add transaction
60 85
61 - try {  
62 - //@todo add transaction  
63 - // попытаемся вставить данные в БД с апдейтом по ключам  
64 - $details_model->ManualInsert($this->data);  
65 -  
66 - // 3. зафиксируем дату конца загрузки в файлах поставщика 86 + if ((int)$this->configuration['delete_prefix']) {
  87 + $details_model->delete_prefix = true;
  88 + }
  89 + if ((int)$this->configuration['delete_price']) {
  90 + $details_model->delete_price = true;
  91 + }
  92 + //2. попытаемся вставить данные в БД с апдейтом по ключам
  93 + $details_model->ManualInsert($this->data, $this->configuration['importer_id']);
67 94
68 - if (!$files_model->save()) {  
69 - throw new \ErrorException(implode( ', ', $files_model->getErrors()));  
70 - } 95 + // 3. зафиксируем дату конца загрузки в файлах поставщика
  96 + if (!$files_model->save()) {
  97 + throw new \ErrorException(implode(', ', $files_model->getErrors()));
  98 + }
71 99
72 - // 4. зафиксируем дату загрузки в таблице поставщиков  
73 - $imp_model = Importers::findOne($this->configuration['importer_id']);  
74 - $imp_model->price_date_update = $update_date; 100 + // 4. зафиксируем дату загрузки в таблице поставщиков
  101 + $imp_model = Importers::findOne($this->configuration['importer_id']);
  102 + $imp_model->price_date_update = $update_date;
75 103
76 - if (!$imp_model->save()) {  
77 - throw new \ErrorException(implode( ', ', $imp_model->getErrors()));  
78 - }  
79 - } catch (ErrorException $e) {  
80 - throw new \ErrorException( $e->getMessage() ); 104 + if (!$imp_model->save()) {
  105 + throw new \ErrorException(implode(', ', $imp_model->getErrors()));
81 } 106 }
82 - 107 + } catch (ErrorException $e) {
  108 + throw new \ErrorException($e->getMessage());
  109 + }
83 110
84 111
85 return true; 112 return true;
test1.zip deleted
No preview for this file type