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 101 }
102 102  
103 103 $model->file->saveAs($model->file_path);
104   -
105 104 // для авто загрузки, обработка завершена
106 105 if ($model->mode) {
107 106 $model->success = true;
... ... @@ -124,12 +123,11 @@ class ParserController extends BaseController
124 123  
125 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 133 } else if (Yii::$app->getCache()->get('parser_data')) {
... ... @@ -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 152 return $this->render('results',
152 153 ['model' => $data,
... ...
backend/models/Details.php
... ... @@ -2,6 +2,7 @@
2 2  
3 3 namespace backend\models;
4 4  
  5 +use common\components\CustomVarDamp;
5 6 use Yii;
6 7 use backend\components\base\BaseActiveRecord;
7 8  
... ... @@ -22,8 +23,22 @@ use backend\components\base\BaseActiveRecord;
22 23 */
23 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 34 const BATCH = 500;
  35 +
  36 + /**
  37 + * @var bool - признак необходимости удалить префикс Артикула перед вставкой
  38 + */
  39 + public $delete_prefix = false;
  40 + public $delete_price = false;
  41 +
27 42 /**
28 43 * @inheritdoc
29 44 */
... ... @@ -38,8 +53,8 @@ class Details extends BaseActiveRecord
38 53 public function rules()
39 54 {
40 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 58 [['PRICE'], 'number'],
44 59 [['BOX'], 'integer'],
45 60 [['timestamp'], 'safe'],
... ... @@ -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 114 // \common\components\CustomVarDamp::dumpAndDie($data);
75 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 120 $query_update = ' on duplicate key update ';
81 121 foreach ($fields_arr_to_update as $field) {
... ... @@ -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 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 140 }
101 141 }
102 142  
103   -
104 143 }
... ...
backend/models/UploadFileParsingForm.php
... ... @@ -77,7 +77,9 @@ class UploadFileParsingForm extends Model
77 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 83 return $data;
82 84 }
83 85  
... ...
common/components/PriceWriter.php
... ... @@ -14,22 +14,45 @@ use backend\models\ImportersFiles;
14 14 use backend\models\Importers;
15 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 28 public $mode;
  29 +
  30 + /**
  31 + * @var - массив с настройками записи
  32 + */
19 33 public $configuration;
  34 +
  35 + /**
  36 + * @var - массив с данными которые нужно записать
  37 + */
20 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 47 // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles)
25 48 // id загруженного файла получим из конфигурации
26   - $files_model = ImportersFiles::findOne( $this->configuration['record_id'] );
  49 + $files_model = ImportersFiles::findOne($this->configuration['record_id']);
27 50  
28 51 $update_date = date('Y-m-d H:i:s');
29 52 $files_model->time_start = $update_date;
30 53 // запишем дату начала загрузки
31 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 58 // 2. запишем полученные данные в таблицу товаров (Details)
... ... @@ -43,7 +66,7 @@ class PriceWriter {
43 66 $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']);
44 67 // присвоим полный артикул
45 68 $row['FULL_ARTICLE'] = $row['ARTICLE'];
46   - if(isset($row['ADD_BOX']))
  69 + if (isset($row['ADD_BOX']))
47 70 $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']);
48 71  
49 72 // проверим все ли обязательные колонки были указаны пользователем
... ... @@ -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 112 return true;
... ...
test1.zip deleted
No preview for this file type