Commit e8ccb1b4b180af34bea03cadb3d4cb9591462214

Authored by Yarik
1 parent 14cd7eed

Import beta

common/modules/language/behaviors/LanguageBehavior.php
... ... @@ -271,6 +271,9 @@
271 271 $this->_transaction->commit();
272 272 $this->_transaction_status = true;
273 273 }
  274 + if($owner->hasAttribute('remote_id') && empty($owner->remote_id)) {
  275 + $owner->remote_id = (int) $owner->primaryKey;
  276 + }
274 277 }
275 278  
276 279 /**
... ...
common/modules/language/models/Language.php
... ... @@ -17,7 +17,10 @@
17 17 */
18 18 class Language extends \yii\db\ActiveRecord
19 19 {
20   -
  20 +
  21 + /**
  22 + * @var null|self
  23 + */
21 24 public static $current = null;
22 25  
23 26 /**
... ...
common/modules/product/controllers/ManageController.php
... ... @@ -4,6 +4,7 @@
4 4  
5 5 use common\models\ProductCertificate;
6 6 use common\models\ProductSpec;
  7 + use common\modules\language\models\Language;
7 8 use common\modules\product\models\Export;
8 9 use common\modules\product\models\Import;
9 10 use common\modules\product\models\ProductImage;
... ... @@ -313,7 +314,19 @@
313 314 {
314 315 $model = new Import();
315 316  
  317 + $languages = Language::find()
  318 + ->select([
  319 + 'name',
  320 + 'language_id',
  321 + ])
  322 + ->where([ 'status' => 1 ])
  323 + ->orderBy([ 'default' => SORT_DESC ])
  324 + ->asArray()
  325 + ->indexBy('language_id')
  326 + ->column();
  327 +
316 328 if($model->load(Yii::$app->request->post())) {
  329 + \Yii::$app->session->set('export_lang', $model->lang);
317 330 $file = UploadedFile::getInstances($model, 'file');
318 331 $method = 'go' . ucfirst($model->type);
319 332 $target = Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFile' . ucfirst($model->type));
... ... @@ -337,7 +350,8 @@
337 350 }
338 351  
339 352 return $this->render('import', [
340   - 'model' => $model,
  353 + 'model' => $model,
  354 + 'languages' => $languages,
341 355 ]);
342 356 }
343 357  
... ... @@ -349,7 +363,7 @@
349 363  
350 364 if(Yii::$app->request->isAjax) {
351 365 Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
352   - return $model->goProducts($from, 10);
  366 + return $model->goProducts($from, 1);
353 367 }
354 368 }
355 369  
... ... @@ -371,7 +385,7 @@
371 385 $model = new Export();
372 386 if(Yii::$app->request->isAjax) {
373 387 Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
374   - return $model->process($filename,$from);
  388 + return $model->process($filename, $from);
375 389 }
376 390 }
377 391  
... ... @@ -382,8 +396,8 @@
382 396 if($model->load(Yii::$app->request->post())) {
383 397 \Yii::$app->session->set('export_lang', $model->lang);
384 398 return $this->render('export-process', [
385   - 'model' => $model,
386   - 'method' => 'export',
  399 + 'model' => $model,
  400 + 'method' => 'export',
387 401 ]);
388 402 }
389 403  
... ...
common/modules/product/models/Import.php
1 1 <?php
2   -
3   -namespace common\modules\product\models;
4   -
5   -use common\modules\rubrication\models\TaxGroup;
6   -use common\modules\rubrication\models\TaxOption;
7   -use Yii;
8   -use yii\base\Model;
9   -use yii\helpers\ArrayHelper;
10   -
11   -class Import extends Model {
12   - public $file;
13   - public $type;
14   -
15   - public $errors = [];
16   - public $output = [];
17   -
18   - /**
19   - * @inheritdoc
20   - */
21   - public function rules()
22   - {
23   - return [
24   - [['type'], 'required'],
25   - [['type'], 'string'],
26   - [['file'], 'file', 'extensions' => 'csv'],
27   - ];
28   - }
29   -
30   - /**
31   - * @inheritdoc
32   - */
33   - public function attributeLabels()
  2 +
  3 + namespace common\modules\product\models;
  4 +
  5 + use common\modules\language\models\Language;
  6 + use common\modules\rubrication\models\TaxGroup;
  7 + use common\modules\rubrication\models\TaxOption;
  8 + use Yii;
  9 + use yii\base\Model;
  10 + use yii\helpers\ArrayHelper;
  11 +
  12 + class Import extends Model
34 13 {
35   - return [
36   - 'file' => Yii::t('product', 'File'),
37   - ];
38   - }
39   -
40   - public function getType() {
41   - if (!$this->type) {
42   - $this->type = 'products';
43   - }
44   - return $this->type;
45   - }
46   -
47   - public function goPrices($from = 0, $limit = null) {
48   - set_time_limit(0);
49   -
50   - if ( !($handle = $this->getProductsFile('uploadFilePrices')) ) {
51   - $this->errors[] = 'File not found';
52   - return FALSE;
  14 +
  15 + public $file;
  16 +
  17 + public $type;
  18 +
  19 + public $lang;
  20 +
  21 + public $errors = [];
  22 +
  23 + public $output = [];
  24 +
  25 + /**
  26 + * @inheritdoc
  27 + */
  28 + public function rules()
  29 + {
  30 + return [
  31 + [
  32 + [
  33 + 'type',
  34 + 'lang',
  35 + ],
  36 + 'required',
  37 + ],
  38 + [
  39 + [ 'lang' ],
  40 + 'integer',
  41 + ],
  42 + [
  43 + [ 'type' ],
  44 + 'string',
  45 + ],
  46 + [
  47 + [ 'file' ],
  48 + 'file',
  49 + 'extensions' => 'csv',
  50 + ],
  51 + ];
53 52 }
54   -
55   - $filesize = filesize(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFilePrices'));
56   - if ($from) {
57   - fseek($handle, $from);
  53 +
  54 + /**
  55 + * @inheritdoc
  56 + */
  57 + public function attributeLabels()
  58 + {
  59 + return [
  60 + 'file' => Yii::t('product', 'File'),
  61 + ];
58 62 }
59   -
60   - $j = 0;
61   -
62   - $is_utf = (preg_match('//u', file_get_contents(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFilePrices'), null, null, null, 1000000)));
63   -
64   - while (($data = fgetcsv ($handle, 10000, ";")) !== FALSE && (empty($limit) || $j++ < $limit))
  63 +
  64 + public function getType()
65 65 {
66   - foreach ($data as &$value)
67   - {
68   - if (!$is_utf) {
69   - $value = iconv ('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value);
70   - }
71   - $value = trim ($value);
72   - }
73   -
74   - // данные строк
75   - $modification_code = @$data[0];
76   - $price = floatval(@$data[1]);
77   - $price_promo = floatval(@$data[2]);
78   - $count = intval(@$data[3]);
79   - $city_name = @$data[4];
80   - $product_title = @$data[5];
81   -
82   - if (empty ($modification_code)) {
83   - continue;
  66 + if(!$this->type) {
  67 + $this->type = 'products';
84 68 }
85   - // товары в пути
86   - if (empty ($city_name))
87   - {
88   - $this->output[] = 'Товар '. $product_title . ' в пути';
89   - continue;
  69 + return $this->type;
  70 + }
  71 +
  72 + public function goPrices($from = 0, $limit = NULL)
  73 + {
  74 + set_time_limit(0);
  75 +
  76 + if(!( $handle = $this->getProductsFile('uploadFilePrices') )) {
  77 + $this->errors[] = 'File not found';
  78 + return false;
90 79 }
91   -
92   - if ( ($productVariant = ProductVariant::find()->filterWhere(['sku' => $modification_code])->one()) === null ) {
93   - $this->output[] = 'Для товара '. $product_title . ' не найдено соотвествие';
94   - continue;
  80 +
  81 + $filesize = filesize(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices'));
  82 + if($from) {
  83 + fseek($handle, $from);
95 84 }
96   - // ===== Set stock ====
97   - if ( $city_name ) {
98   - if ( ($stock = Stock::find()->filterWhere(['name' => trim($city_name)])->one()) === null ) {
99   - // Create stock
100   - $stock = new Stock();
101   - $stock->name = trim($city_name);
102   - $stock->save();
  85 +
  86 + $j = 0;
  87 +
  88 + $is_utf = ( preg_match('//u', file_get_contents(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices'), NULL, NULL, NULL, 1000000)) );
  89 +
  90 + while(( empty( $limit ) || $j++ < $limit ) && ( $data = fgetcsv($handle, 10000, ";") ) !== false) {
  91 + foreach($data as &$value) {
  92 + if(!$is_utf) {
  93 + $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value);
  94 + }
  95 + $value = trim($value);
103 96 }
104   -
105   - $productStock = ProductStock::find()->where(['product_variant_id' => $productVariant->product_variant_id, 'stock_id' => $stock->stock_id])->one();
106   - if(!$productStock instanceof ProductStock) {
107   - $productStock = new ProductStock;
108   - $productStock->product_variant_id = $productVariant->product_variant_id;
109   - $productStock->stock_id = $stock->stock_id;
110   - $productStock->product_id = $productVariant->product_id;
  97 +
  98 + // данные строк
  99 + $modification_code = @$data[ 0 ];
  100 + $price = floatval(@$data[ 1 ]);
  101 + $price_promo = floatval(@$data[ 2 ]);
  102 + $count = intval(@$data[ 3 ]);
  103 + $city_name = @$data[ 4 ];
  104 + $product_title = @$data[ 5 ];
  105 +
  106 + if(empty ( $modification_code )) {
  107 + continue;
111 108 }
112   - $productStock->quantity = $count;
113   -
114   - $productStock->save();
115   - $productStocks = ProductStock::find()->where(['product_variant_id' => $productVariant->product_variant_id])->andWhere(['<>', 'stock_id', $stock->stock_id])->all();
116   -
117   - $quantity = array_sum(ArrayHelper::getColumn($productStocks, 'quantity')) + $count;
118   - } else {
119   -
120   - $productStocks = ProductStock::find()->where(['product_variant_id' => $productVariant->product_variant_id])->all();
121   -
122   - if($productStocks instanceof ProductStock){
  109 + // товары в пути
  110 + if(empty ( $city_name )) {
  111 + $this->output[] = 'Товар ' . $product_title . ' в пути';
  112 + continue;
  113 + }
  114 +
  115 + if(( $productVariant = ProductVariant::find()
  116 + ->filterWhere([ 'sku' => $modification_code ])
  117 + ->one() ) === NULL
  118 + ) {
  119 + $this->output[] = 'Для товара ' . $product_title . ' не найдено соотвествие';
  120 + continue;
  121 + }
  122 + // ===== Set stock ====
  123 + if($city_name) {
  124 + if(( $stock = Stock::find()
  125 + ->filterWhere([ 'name' => trim($city_name) ])
  126 + ->one() ) === NULL
  127 + ) {
  128 + // Create stock
  129 + $stock = new Stock();
  130 + $stock->name = trim($city_name);
  131 + $stock->save();
  132 + }
  133 +
  134 + $productStock = ProductStock::find()
  135 + ->where([
  136 + 'product_variant_id' => $productVariant->product_variant_id,
  137 + 'stock_id' => $stock->stock_id,
  138 + ])
  139 + ->one();
  140 + if(!$productStock instanceof ProductStock) {
  141 + $productStock = new ProductStock;
  142 + $productStock->product_variant_id = $productVariant->product_variant_id;
  143 + $productStock->stock_id = $stock->stock_id;
  144 + $productStock->product_id = $productVariant->product_id;
  145 + }
  146 + $productStock->quantity = $count;
  147 +
  148 + $productStock->save();
  149 + $productStocks = ProductStock::find()
  150 + ->where([ 'product_variant_id' => $productVariant->product_variant_id ])
  151 + ->andWhere([
  152 + '<>',
  153 + 'stock_id',
  154 + $stock->stock_id,
  155 + ])
  156 + ->all();
  157 +
123 158 $quantity = array_sum(ArrayHelper::getColumn($productStocks, 'quantity')) + $count;
124 159 } else {
125   - $quantity = 0;
  160 +
  161 + $productStocks = ProductStock::find()
  162 + ->where([ 'product_variant_id' => $productVariant->product_variant_id ])
  163 + ->all();
  164 +
  165 + if($productStocks instanceof ProductStock) {
  166 + $quantity = array_sum(ArrayHelper::getColumn($productStocks, 'quantity')) + $count;
  167 + } else {
  168 + $quantity = 0;
  169 + }
  170 +
126 171 }
127   -
  172 +
  173 + if($price_promo) {
  174 + $productVariant->price_old = $price;
  175 + $productVariant->price = $price_promo;
  176 + } else {
  177 + $productVariant->price = $price;
  178 + $productVariant->price_old = $price_promo;
  179 + }
  180 +
  181 + $productVariant->stock = $quantity;
  182 +
  183 + $productVariant->save();
  184 +
  185 + $this->output[] = '<font style="color:blue">Товар ' . $product_title . ' успешно сохранен</font>';
128 186 }
129   -
130   - if ($price_promo) {
131   - $productVariant->price_old = $price;
132   - $productVariant->price = $price_promo;
133   - } else {
134   - $productVariant->price = $price;
135   - $productVariant->price_old = $price_promo;
  187 +
  188 + $result = [
  189 + 'end' => feof($handle),
  190 + 'from' => ftell($handle),
  191 + 'totalsize' => $filesize,
  192 + 'items' => $this->output,
  193 +
  194 + ];
  195 +
  196 + fclose($handle);
  197 +
  198 + if($result[ 'end' ]) {
  199 + unlink(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFilePrices'));
136 200 }
137   -
138   - $productVariant->stock = $quantity;
139   -
140   - $productVariant->save();
141   -
142   - $this->output[] = '<font style="color:blue">Товар '. $product_title .' успешно сохранен</font>';
143   - }
144   -
145   - $result = [
146   - 'end' => feof($handle),
147   - 'from' => ftell($handle),
148   - 'totalsize' => $filesize,
149   - 'items' => $this->output,
150   -
151   - ];
152   -
153   - fclose ($handle);
154   -
155   - if ($result['end']) {
156   - unlink(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFilePrices'));
157   - }
158   -
159   - return $result;
160   - }
161   -
162   - public function goProducts($from = 0, $limit = null) {
163   -
164   - set_time_limit(0);
165   -
166   - if ( !($handle = $this->getProductsFile('uploadFileProducts')) ) {
167   - $this->errors[] = 'File not found';
168   - return FALSE;
  201 +
  202 + return $result;
169 203 }
170   -
171   - $filesize = filesize(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'));
172 204  
173   - if ($from) {
174   - fseek($handle, $from);
175   - }
176   -
177   - $j = 0;
178   -
179   - $is_utf = (preg_match('//u', file_get_contents(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'), null, null, null, 1000000)));
180   -
181   - $result_items = [];
182   -
183   - while (($data = fgetcsv ($handle, 10000, ";")) !== FALSE && (empty($limit) || $j++ < $limit))
  205 + /**
  206 + * @param string $name
  207 + *
  208 + * @return array
  209 + */
  210 + private function parseName(string $name):array
184 211 {
185   - foreach ($data as &$value)
186   - {
187   - if (!$is_utf) {
188   - $value = iconv ('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value);
189   - }
190   - $value = trim ($value);
191   - }
192   - // будет всегда 19 элементов
193   - for ($i = 0; $i <= 18; $i++)
194   - {
195   - if (! isset ($data[$i]))
196   - {
197   - $data[$i] = null;
  212 + $pattern = '/^(?P<name>.*)(?:\(#(?P<remote_id>\w+)#\))?$/U';
  213 + $name = trim($name);
  214 + $matches = [];
  215 + if(preg_match($pattern, $name, $matches)) {
  216 + if(!isset($matches['remote_id'])) {
  217 + $matches['remote_id'] = '';
198 218 }
  219 + return $matches;
199 220 }
200   - // 1 Группа (категория)
201   - $catalog_names = explode(',',$data[0]);
202   - if (empty ($catalog_names))
203   - {
204   - $result_items[] = "Не указана категория (строка $j)";
205   - continue;
206   - }
207   -
208   - // 2 Бренд
209   - $brand_name = $data[1];
210   - if (empty ($brand_name))
211   - {
212   - $result_items[] = "Не указан бренд (строка $j)";
213   - continue;
214   - }
215   -
216   - // 3 Название товара
217   - $product_name = $data[2];
218   - if (empty ($product_name))
219   - {
220   - $result_items[] = "Не указано наименование товара (строка $j)";
221   - continue;
222   - }
223   -
224   - // 4 Описание Укр
225   - $product_body_uk = $data[3];
226   -
227   - // 5 Описание Рус
228   - $product_body_ru = $data[4];
229   -
230   - // 6 Фильтр
231   - $filters = explode ('*', $data[5]);
232   -
233   - // 11 Цена акция
234   - $product_cost_old = floatval($data[7]);
235   -
236   - // 10 Цена
237   - if ($product_cost_old) {
238   - $product_cost_old = floatval($data[6]);
239   - $product_cost = floatval($data[7]);
240   - }
241   -
242   - // 12 Акция
243   - $product_akciya = (bool)$data[8];
244   -
245   - // 13 Сопуд. Тов.
246   - $similar = explode (',', $data[9]);
247   -
248   - // 14 Новинки
249   - $product_new = (bool)$data[10];
250   -
251   - // 15 Топ продаж
252   - $product_top = (bool)$data[11];
253   -
254   - // 17 ВИДЕО КОД
255   - $product_video = $data[12];
256   -
257   - // 18 Галлерея фото
258   - if (trim($data[13])) {
259   - $fotos = explode (',', trim($data[13]));
260   - }
261   -
262   - // 19 Штрих код товара.
263   - // расшифровал - это модификации товара!
264   -
265   - $product_image = explode ('=', $data[14]);
266   - $product_image = @$product_image[3];
267   -
268   - if ( ($_product = Product::find()->filterWhere(['ilike', 'name', trim($product_name)])->one()) === null ) {
269   - $_product = new Product();
270   - }
271   -
272   - $is_new_product = empty($_product->product_id);
273   -
  221 + return [
  222 + 'name' => $name,
  223 + 'remote_id' => '',
  224 + ];
  225 + }
  226 +
  227 + /**
  228 + * @param array $catalog_names
  229 + *
  230 + * @return array
  231 + * @throws \Exception
  232 + */
  233 + private function saveCatalog(array $catalog_names):array
  234 + {
274 235 $category_id = [];
275 236  
276   - foreach($catalog_names as $catalog_name){
  237 + foreach($catalog_names as $catalog_name) {
277 238 // ==== Set category ====
278   - if ( ($category = Category::find()->filterWhere(['ilike', 'name', trim($catalog_name)])->one()) === null ) {
  239 + $parsed_name = $this->parseName($catalog_name);
  240 + if(!empty($parsed_name['remote_id']) && ( $category = Category::find()
  241 + ->joinWith('lang')
  242 + ->andFilterWhere([ 'remote_id' => $parsed_name[ 'remote_id' ] ])
  243 + ->one() ) !== NULL
  244 + ) {
  245 + if(!empty( $category->lang )) {
  246 + $category->lang->name = $parsed_name[ 'name' ];
  247 + $category->lang->save();
  248 + } else {
  249 + throw new \Exception('Category with ID ' . $category->category_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  250 + }
  251 +
  252 + } else {
279 253 // Create category
280 254 $category = new Category();
281   - $category->name = trim($catalog_name);
  255 + $category->generateLangs();
  256 + $category_langs = $category->model_langs;
  257 + foreach($category_langs as $category_lang) {
  258 + $category_lang->name = $parsed_name[ 'name' ];
  259 + }
  260 + $category->remote_id = $parsed_name[ 'remote_id' ];
282 261 $category->save();
283 262 }
284 263 $category_id[] = $category->category_id;
285 264 }
286   -
287   - $_product->categories = $category_id;
288   -
289   - // ===== Set brand ====
290   - if ( $brand_name ) {
  265 + return $category_id;
  266 + }
  267 +
  268 + /**
  269 + * @param string|NULL $brand_name
  270 + *
  271 + * @return int|null
  272 + * @throws \Exception
  273 + */
  274 + private function saveBrand(string $brand_name = NULL):int
  275 + {
  276 +
  277 + $parsed_name = $this->parseName($brand_name);
  278 + if(!empty( $brand_name )) {
291 279 /**
292 280 * @var Brand $brand
293 281 */
294   - if ( ($brand = Brand::find()->filterWhere(['ilike', 'name', trim($brand_name)])->one()) !== null ) {
295   - $_product->brand_id = $brand->brand_id;
  282 + if(!empty($parsed_name['remote_id']) && ($brand = Brand::find()
  283 + ->joinWith('lang')
  284 + ->andFilterWhere([ 'remote_id' => $parsed_name[ 'remote_id' ] ])
  285 + ->one() ) !== NULL
  286 + ) {
  287 + if(!empty( $brand->lang )) {
  288 + $brand->lang->name = $parsed_name[ 'name' ];
  289 + $brand->lang->save();
  290 + } else {
  291 + throw new \Exception('Brand with ID ' . $brand->brand_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  292 + }
  293 + return $brand->brand_id;
296 294 } else {
297 295 // Create brand
298 296 $brand = new Brand();
299   - $brand->name = trim($brand_name);
  297 + $brand->generateLangs();
  298 + $brand_langs = $brand->model_langs;
  299 + foreach($brand_langs as $brand_lang) {
  300 + $brand_lang->name = $parsed_name[ 'name' ];
  301 + }
  302 + $brand->remote_id = $parsed_name[ 'remote_id' ];
300 303 $brand->save();
301   - $_product->brand_id = $brand->brand_id;
  304 + return $brand->brand_id;
302 305 }
303 306 }
304   -
305   - $_product->name = $product_name;
306   - $_product->video = $product_video;
307   - $_product->description = $product_body_ru;
308   - $_product->is_top = $product_top;
309   - $_product->akciya = $product_akciya;
310   - $_product->is_new = $product_new;
311   -
312   - if (!$_product->save()) {
313   - $result_items[] = 'Product #'. $_product->name .' not saved' . " (строка $j)";
314   - continue;
315   - }
316   -
317   - if (!empty($fotos)) {
  307 + return NULL;
  308 + }
  309 +
  310 + /**
  311 + * @param array $fotos
  312 + * @param int $product_id
  313 + * @param int $product_variant_id
  314 + */
  315 + private function saveFotos(array $fotos, int $product_id, int $product_variant_id = NULL)
  316 + {
  317 + if(!empty( $fotos )) {
318 318 foreach($fotos as $foto) {
319   - $source_image = Yii::getAlias('@uploadDir') . '/product_images/'. urlencode($foto);
320   -
321   - if (file_exists($source_image)) {
322   - if (($productImage = ProductImage::find()->andFilterWhere(['ilike', 'image', $foto])->andFilterWhere(['product_id' => $_product->product_id])->one()) === null) {
  319 + $source_image = Yii::getAlias('@uploadDir') . '/product_images/' . urlencode($foto);
  320 + if(file_exists($source_image)) {
  321 + if(( $productImage = ProductImage::find()
  322 + ->andWhere([ 'image' => $foto ])
  323 + ->andWhere([ 'product_id' => $product_id ])
  324 + ->andFilterWhere([ 'product_variant_id' => $product_variant_id ])
  325 + ->one() ) === NULL
  326 + ) {
323 327 copy($source_image, Yii::getAlias('@productsDir') . "/" . $foto);
324 328 $productImage = new ProductImage();
325   - $productImage->product_id = $_product->product_id;
  329 + $productImage->product_id = $product_id;
  330 + $productImage->product_variant_id = $product_variant_id;
326 331 $productImage->image = $foto;
327 332 $productImage->save();
328 333 }
329 334 }
330 335 }
331 336 }
332   -
333   - // нужно для проставления характеристик относящихся к модификациям
  337 + }
  338 +
  339 + /**
  340 + * @param array $data
  341 + * @param float $product_cost_old
  342 + * @param float $product_cost
  343 + * @param int $product_id
  344 + * @param array $category_id
  345 + *
  346 + * @return array
  347 + */
  348 + private function saveVariants(array $data, float $product_cost_old, int $product_id, array $category_id, float $product_cost = NULL):array
  349 + {
334 350 $MOD_ARRAY = [];
335   -
336   - for ($i = 14; $i < count ($data); $i ++)
337   - {
338   - if (! empty ($data[$i]))
339   - {
340   - $mod_arr = explode ('=', $data[$i]);
341   - $mod_art = $mod_arr[0];
342   - $variant_filters = explode ('*', $mod_arr[1]);
343   - $mod_color = $mod_arr[2];
344   - $mod_image = $mod_arr[3];
345   - $mod_stock = isset($mod_arr[4]) ?$mod_arr[4]:1;
346   - $mod_cost = isset($product_cost) ? floatval($product_cost) : 0;
  351 + for($i = 13; $i < count($data); $i++) {
  352 + if(!empty ( $data[ $i ] )) {
  353 + $mod_arr = explode('=', $data[ $i ]);
  354 + $mod_art = $mod_arr[ 0 ];
  355 + $variant_filters = explode('*', $mod_arr[ 1 ]);
  356 + $mod_name = $mod_arr[ 2 ];
  357 + if(empty( $mod_name )) {
  358 + $mod_name = $mod_art;
  359 + }
  360 + $mod_image = $mod_arr[ 3 ];
  361 + $mod_stock = isset( $mod_arr[ 4 ] ) ? $mod_arr[ 4 ] : 1;
  362 + $mod_cost = isset( $product_cost ) ? floatval($product_cost) : 0;
347 363 $mod_old_cost = floatval($product_cost_old);
348 364 // Check product variant
349   - if ( ($_productVariant = ProductVariant::find()->andFilterWhere(['ilike', 'sku', $mod_art])->andFilterWhere(['product_id' => $_product->product_id])->one()) === null ) {
  365 + /**
  366 + * @var ProductVariant $_productVariant
  367 + */
  368 + if(( $_productVariant = ProductVariant::find()
  369 + ->joinWith('lang')
  370 + ->andFilterWhere([ 'sku' => $mod_art ])
  371 + ->andFilterWhere([ 'product_variant.product_id' => $product_id ])
  372 + ->one() ) === NULL
  373 + ) {
350 374 $_productVariant = new ProductVariant();
351   - $_productVariant->product_id = $_product->product_id;
  375 + $_productVariant->product_id = $product_id;
  376 + $_productVariant->generateLangs();
  377 + $product_variant_langs = $_productVariant->model_langs;
  378 + foreach($product_variant_langs as $product_variant_lang) {
  379 + $product_variant_lang->name = $mod_name;
  380 + }
  381 + } else {
  382 + if(!empty( $_productVariant->lang )) {
  383 + $_productVariant->lang->name = $mod_name;
  384 + $_productVariant->lang->save();
  385 + } else {
  386 + throw new \Exception('Product variant with ID ' . $_productVariant->product_variant_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  387 + }
352 388 }
353 389 $_productVariant->product_unit_id = 1;
354 390 $_productVariant->sku = $mod_art;
355 391 $_productVariant->price = $mod_cost;
356 392 $_productVariant->price_old = $mod_old_cost;
357 393 $_productVariant->stock = $mod_stock;
358   -
359   - if (! empty ($mod_color)) {
360   - $_productVariant->name = $mod_color;
  394 +
  395 + if(!empty ( $variant_filters )) {
  396 + $variants_options = $this->saveFilters($variant_filters, 1, $category_id);
361 397 }
362   -
363   - if (! empty ($variant_filters)) {
364   - $variants_options = $this->saveFilters($variant_filters,1,$category_id);
365   - }
366   -
367   -
368   - if (isset($variants_options) && !empty($variants_options)) {
  398 +
  399 + if(isset( $variants_options ) && !empty( $variants_options )) {
369 400 $_productVariant->options = $variants_options;
370 401 }
371   -
  402 +
  403 + /**
  404 + * @todo set to false
  405 + */
372 406 $_productVariant->save(false);
373   -
  407 +
374 408 $MOD_ARRAY[] = $_productVariant->product_variant_id;
  409 +
  410 + $this->saveFotos([ $mod_image ], $product_id, $_productVariant->product_variant_id);
  411 + }
  412 + }
  413 + return $MOD_ARRAY;
  414 + }
  415 +
  416 + private function debug($start_time, $message) {
  417 + echo $message.': '.(time()-$start_time).'s passed';
  418 + }
  419 +
  420 + public function goProducts($from = 0, $limit = NULL)
  421 + {
  422 + $start_time = time();
  423 + set_time_limit(0);
  424 +
  425 + if(!( $handle = $this->getProductsFile('uploadFileProducts') )) {
  426 + $this->errors[] = 'File not found';
  427 + return false;
  428 + }
375 429  
376   - if ($mod_image) {
377   - $source_image = Yii::getAlias('@uploadDir') . '/product_images/'. urlencode($mod_image);
378   - if (file_exists($source_image)) {
379   - if (($variantImage = ProductImage::find()->andFilterWhere(['ilike', 'image', $mod_image])->andFilterWhere(['product_variant_id' => $_productVariant->product_variant_id])->one()) === null) {
380   - copy($source_image, Yii::getAlias('@productsDir') . "/" . $mod_image);
381   - $variantImage = new ProductImage();
382   - $variantImage->product_id = $_product->product_id;
383   - $variantImage->product_variant_id = $_productVariant->product_variant_id;
384   - $variantImage->image = $mod_image;
385   - $variantImage->save();
386   - }
  430 + $filesize = filesize(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts'));
  431 +
  432 + if($from) {
  433 + fseek($handle, $from);
  434 + }
  435 +
  436 + $j = 0;
  437 +
  438 + $is_utf = ( preg_match('//u', file_get_contents(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts'), NULL, NULL, NULL, 1000000)) );
  439 +
  440 + $result_items = [];
  441 +
  442 + while(( empty( $limit ) || $j++ < $limit ) && ( $data = fgetcsv($handle, 10000, ";") ) !== false) {
  443 +
  444 + try {
  445 + foreach($data as &$value) {
  446 + if(!$is_utf) {
  447 + $value = iconv('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value);
  448 + }
  449 + $value = trim($value);
  450 + }
  451 + // будет всегда 19 элементов
  452 + for($i = 0; $i <= 18; $i++) {
  453 + if(!isset ( $data[ $i ] )) {
  454 + $data[ $i ] = NULL;
  455 + }
  456 + }
  457 + // 1 Группа (категория)
  458 + $catalog_names = explode(',', $data[ 0 ]);
  459 + if(empty ( $catalog_names )) {
  460 + $result_items[] = "Не указана категория (строка $j)";
  461 + continue;
  462 + }
  463 +
  464 + // 2 Бренд
  465 + $brand_name = $data[ 1 ];
  466 + // if(empty ( $brand_name )) {
  467 + // $result_items[] = "Не указан бренд (строка $j)";
  468 + // continue;
  469 + // }
  470 +
  471 + // 3 Название товара
  472 + $product_name = $data[ 2 ];
  473 + if(empty ( $product_name )) {
  474 + $result_items[] = "Не указано наименование товара (строка $j)";
  475 + continue;
  476 + }
  477 +
  478 + // 5 Описание товара
  479 + $product_body = $data[ 3 ];
  480 +
  481 + // 6 Фильтр
  482 + $filters = explode('*', $data[ 4 ]);
  483 +
  484 + // 11 Цена акция
  485 + $product_cost_old = floatval($data[ 6 ]);
  486 +
  487 + $product_cost = NULL;
  488 + // 10 Цена
  489 + if($product_cost_old) {
  490 + $product_cost_old = floatval($data[ 5 ]);
  491 + $product_cost = floatval($data[ 6 ]);
  492 + }
  493 +
  494 + // 12 Акция
  495 + $product_akciya = (bool) $data[ 7 ];
  496 +
  497 + // 13 Сопуд. Тов.
  498 + $similar = explode(',', $data[ 8 ]);
  499 +
  500 + // 14 Новинки
  501 + $product_new = (bool) $data[ 9 ];
  502 +
  503 + // 15 Топ продаж
  504 + $product_top = (bool) $data[ 10 ];
  505 +
  506 + // 17 ВИДЕО КОД
  507 + $product_video = $data[ 11 ];
  508 +
  509 + // 18 Галлерея фото
  510 + $fotos = [];
  511 + if(trim($data[ 12 ])) {
  512 + $fotos = explode(',', trim($data[ 12 ]));
  513 + }
  514 +
  515 +// $lang = \Yii::$app->session->get('export_lang', Language::getDefaultLanguage()->language_id);
  516 +// /**
  517 +// * @var Language $language
  518 +// */
  519 +// $language = Language::find()
  520 +// ->where([ 'language_id' => $lang ])
  521 +// ->one();
  522 +// Language::setCurrent($language->url);
  523 + $start_time = time();
  524 + $categories = $this->saveCatalog($catalog_names);
  525 + $this->debug($start_time, 'Categories');
  526 + $start_time = time();
  527 + $brand_id = $this->saveBrand($brand_name);
  528 + $this->debug($start_time, 'Brands');
  529 +
  530 + $options = [];
  531 + if(!empty ( $filters )) {
  532 + $start_time = time();
  533 + $options = $this->saveFilters($filters, 0, $categories);
  534 + $this->debug($start_time, 'saveFilters');
  535 + }
  536 + $parsed_name = $this->parseName($product_name);
  537 + /**
  538 + * @var Product $_product
  539 + */
  540 + $start_time = time();
  541 + if(!empty($parsed_name['remote_id']) && ( $_product = Product::find()
  542 + ->joinWith('lang')
  543 + ->andFilterWhere([ 'remote_id' => $parsed_name[ 'remote_id' ] ])
  544 + ->one() ) !== NULL
  545 + ) {
  546 + if(!empty( $_product->lang )) {
  547 + $_product->lang->name = $parsed_name[ 'name' ];
  548 + $_product->lang->description = $product_body;
  549 + $_product->lang->save();
  550 + } else {
  551 + throw new \Exception('Product with ID ' . $_product->product_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  552 + }
  553 + } else {
  554 + $_product = new Product();
  555 + $_product->generateLangs();
  556 + $product_langs = $_product->model_langs;
  557 + foreach($product_langs as $product_lang) {
  558 + $product_lang->name = $parsed_name[ 'name' ];
  559 + $product_lang->description = $product_body;
  560 + }
  561 + }
  562 +
  563 + $is_new_product = empty( $_product->product_id );
  564 +
  565 + $_product->categories = $categories;
  566 +
  567 + $_product->brand_id = $brand_id;
  568 +
  569 + $_product->video = $product_video;
  570 + $_product->is_top = $product_top;
  571 + $_product->akciya = $product_akciya;
  572 + $_product->is_new = $product_new;
  573 + $this->debug($start_time, 'Product');
  574 + if(!$_product->save()) {
  575 + if(!empty( $_product->lang )) {
  576 + $product_name_inserted = $_product->lang->name;
  577 + } else {
  578 + $product_name_inserted = $_product->model_langs[ Language::$current->language_id ]->name;
387 579 }
  580 + $result_items[] = 'Product #' . $product_name_inserted . ' not saved' . " (line $j)";
  581 + continue;
388 582 }
  583 + $start_time = time();
  584 + $this->saveFotos($fotos, $_product->product_id);
  585 + $this->debug($start_time, 'saveFotos');
  586 + // нужно для проставления характеристик относящихся к модификациям
  587 + $start_time = time();
  588 + $this->saveVariants($data, $product_cost_old, $_product->product_id, $_product->categories, $product_cost);
  589 + $this->debug($start_time, 'saveVariants');
  590 + if(!empty( $options )) {
  591 + $_product->options = $options;
  592 + }
  593 +
  594 + $_product->save();
  595 +
  596 + $result_items[] = "Product {$_product->lang->name} #{$_product->product_id} saved (" . ( $is_new_product ? 'new product' : 'exists product' ) . ")" . " (line $j)";
  597 +
  598 + } catch(\Exception $e) {
  599 + print $result_items[] = $e->getMessage() . '(line ' . $j . ')';
389 600 }
  601 +
390 602 }
391   -
392   -
393   -
394   - if (! empty ($filters)) {
395   - $options = $this->saveFilters($filters,0,$category_id);
396   - }
397   -
398   -
399   - if (isset($options) && !empty($options)) {
400   - $_product->options = $options;
  603 +
  604 + $result = [
  605 + 'end' => feof($handle),
  606 + 'from' => ftell($handle),
  607 + 'totalsize' => $filesize,
  608 + 'items' => $result_items,
  609 + ];
  610 +
  611 + fclose($handle);
  612 +
  613 + if($result[ 'end' ]) {
  614 +// unlink(Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@uploadFileProducts'));
401 615 }
402   -
403   - $_product->save();
404   -
405   - $result_items[] = "Product {$_product->name} #{$_product->product_id} saved (". ($is_new_product ? 'new product' : 'exists product') .")" . " (строка $j)";
406   - }
407   -
408   - $result = [
409   - 'end' => feof($handle),
410   - 'from' => ftell($handle),
411   - 'totalsize' => $filesize,
412   - 'items' => $result_items,
413   - ];
414   -
415   - fclose ($handle);
416   -
417   - if ($result['end']) {
418   - unlink(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'));
419   - }
420   -
421   - return $result;
422   - }
423   -
424   - private function getProductsFile($file_type) {
425   - $filename = Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@'. $file_type);
426   - if (!is_file($filename)) {
427   - $this->errors[] = "File $filename not found";
428   - return FALSE;
  616 +
  617 + return $result;
429 618 }
430   - return fopen ($filename, 'r');
431   - }
432   -
433   - private function saveNotFoundRecord (array $line, $filename)
434   - {
435   - $str = implode (';', $line)."\n";
436   - $str = iconv ("UTF-8//TRANSLIT//IGNORE", "windows-1251", $str);
437   - $fg = fopen (Yii::getAlias('@uploadDir') .'/'. $filename, 'a+');
438   - fputs ($fg, $str);
439   - fclose ($fg);
440   - }
441   -
442   -
443   - /**
444   - * @param $filters array of filters like [['pol'='мужской'],['god' = '2013'],['volume'='25 л']*['size'='49 x 30 x 20см'],['composition'='600D полиэстер']]
445   - * @param $level 0 for products and 1 for product variant
446   - * @param $catalog_names array catalogs id
447   - * @return array
448   - */
449   - private function saveFilters($filters, $level,$catalog_names){
450   - $options = [];
451   - foreach($filters as $filter) {
452   -
453   - preg_match_all('/\[(.*):(.*)\]/',$filter,$filter);
454   -
455   - if (empty($filter[1][0])) {
456   - continue;
457   - }
458   - $filter_name = trim($filter[1][0]);
459   -
460   - $taxGroup = TaxGroup::find()->where(['alias'=>$filter_name])->one();
461   - if(!$taxGroup instanceof TaxGroup){
462   - $taxGroup = new TaxGroup();
463   - $taxGroup->alias = $filter_name;
464   - $taxGroup->level = $level;
465   - $taxGroup->name = $filter_name;
466   - $taxGroup->categories = $catalog_names;
467   - $taxGroup->is_filter = FALSE;
468   - $taxGroup->save();
  619 +
  620 + private function getProductsFile($file_type)
  621 + {
  622 + $filename = Yii::getAlias('@uploadDir') . '/' . Yii::getAlias('@' . $file_type);
  623 + if(!is_file($filename)) {
  624 + $this->errors[] = "File $filename not found";
  625 + return false;
469 626 }
470   -
471   - $filters_options = explode(',',$filter[2][0]);
472   -
473   - foreach($filters_options as $filter_options){
474   - $option = TaxOption::find()->andFilterWhere(['ilike', 'value', $filters_options])->andFilterWhere(['tax_group_id' => $taxGroup->tax_group_id])->one();
475   -
476   - if ($option === NULL) {
477   - // Create option
478   - $option = new TaxOption();
479   - $option->tax_group_id = $taxGroup->tax_group_id;
480   - $option->value = $filter_options;
481   - $option->save();
  627 + return fopen($filename, 'r');
  628 + }
  629 +
  630 + /**
  631 + * @param $filters array of filters like [['pol'='мужской'],['god' =
  632 + * '2013'],['volume'='25 л']*['size'='49 x 30 x
  633 + * 20см'],['composition'='600D полиэстер']]
  634 + * @param int $level 0 for products and 1 for product variant
  635 + * @param $catalog_names array catalogs id
  636 + *
  637 + * @return array
  638 + * @throws \Exception
  639 + */
  640 + private function saveFilters(array $filters, int $level, array $catalog_names):array
  641 + {
  642 + $options = [];
  643 + foreach($filters as $filter) {
  644 +
  645 + preg_match_all('/\[(.*):(.*)\]/', $filter, $filter);
  646 +
  647 + if(empty( $filter[ 1 ][ 0 ] )) {
  648 + continue;
  649 + }
  650 + $filter_name = trim($filter[ 1 ][ 0 ]);
  651 + $parsed_group_name = $this->parseName($filter_name);
  652 + $start_time = time();
  653 + /**
  654 + * @var TaxGroup $taxGroup
  655 + */
  656 + if(!empty($parsed_group_name['remote_id']) && ($taxGroup = TaxGroup::find()
  657 + ->joinWith('lang')
  658 + ->andFilterWhere([ 'remote_id' => $parsed_group_name[ 'remote_id' ] ])
  659 + ->one()) !== NULL) {
  660 + if(!empty( $taxGroup->lang )) {
  661 + $taxGroup->lang->name = $parsed_group_name[ 'name' ];
  662 + $taxGroup->lang->save();
  663 + } else {
  664 + throw new \Exception('Tax group with ID ' . $taxGroup->tax_group_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  665 + }
  666 + } else {
  667 + $taxGroup = new TaxGroup();
  668 + $taxGroup->generateLangs();
  669 + $tax_group_langs = $taxGroup->model_langs;
  670 + foreach($tax_group_langs as $tax_group_lang) {
  671 + $tax_group_lang->name = $parsed_group_name[ 'name' ];
  672 + }
  673 + $taxGroup->level = $level;
  674 + $taxGroup->categories = $catalog_names;
  675 + $taxGroup->is_filter = false;
  676 + $taxGroup->save();
  677 + }
  678 + print $this->debug($start_time, 'TaxGroup');
  679 + $filters_options = explode(',', $filter[ 2 ][ 0 ]);
  680 + foreach($filters_options as $filter_options) {
  681 + $parsed_option_name = $this->parseName($filter_options);
  682 + /**
  683 + * @var TaxOption $option
  684 + */
  685 + $start_time = time();
  686 + if(!empty($parsed_option_name['remote_id']) && ($option = TaxOption::find()
  687 + ->joinWith('lang')
  688 + ->andFilterWhere([ 'remote_id' => $parsed_option_name[ 'remote_id' ] ])
  689 + ->andFilterWhere([ 'tax_group_id' => $taxGroup->tax_group_id ])
  690 + ->one()) !== NULL) {
  691 + if(!empty( $option->lang )) {
  692 + $option->lang->value = $parsed_option_name[ 'name' ];
  693 + $option->lang->save();
  694 + } else {
  695 + throw new \Exception('Tax option with ID ' . $option->tax_option_id . ' and lang ' . Language::getCurrent()->language_id . ' doesn\'t exist');
  696 + }
  697 + } else {
  698 + // Create option
  699 + $option = new TaxOption();
  700 + $option->generateLangs();
  701 + $option_langs = $option->model_langs;
  702 + foreach($option_langs as $option_lang) {
  703 + $option_lang->value = $parsed_option_name[ 'name' ];
  704 + }
  705 + $option->tax_group_id = $taxGroup->tax_group_id;
  706 + $option->save();
  707 + }
  708 + $options[] = $option->tax_option_id;
  709 + print $this->debug($start_time, 'TaxOption');
482 710 }
483   - $options[] = $option->tax_option_id;
484   -
485 711 }
  712 + return $options;
486 713 }
487   -
488   - return $options;
489   - }
490   -}
491 714 \ No newline at end of file
  715 + }
492 716 \ No newline at end of file
... ...
common/modules/product/models/Product.php
... ... @@ -344,46 +344,51 @@
344 344 ->where([ 'product_id' => $this->product_id ])
345 345 ->sum('quantity');
346 346 }
347   -
  347 +
348 348 public function afterSave($insert, $changedAttributes)
349 349 {
350 350 parent::afterSave($insert, $changedAttributes);
351   -
352   - $this->unlinkAll('categories', true);
353   - $this->unlinkAll('options', true);
354   -
355   - $categories = Category::findAll($this->categories);
356   - $options = TaxOption::findAll($this->options);
357   -
358   - foreach($options as $option) {
359   - $this->link('options', $option);
  351 +
  352 +
  353 + if(!empty($this->categories)){
  354 + $categories = Category::findAll($this->categories);
  355 + $this->unlinkAll('categories', true);
  356 + foreach($categories as $category){
  357 + $this->link('categories', $category);
  358 + }
360 359 }
361   - foreach($categories as $category) {
362   - $this->link('categories', $category);
  360 +
  361 + if(!empty($this->options)){
  362 + $options = TaxOption::findAll($this->options);
  363 + $this->unlinkAll('options',true);
  364 + foreach($options as $option){
  365 + $this->link('options', $option);
  366 + }
363 367 }
364   -
365   - if(!empty( $this->_variants )) {
  368 +
  369 +
  370 + if (!empty($this->_variants)) {
366 371 $todel = [];
367   - foreach($this->variants ? : [] as $_variant) {
368   - $todel[ $_variant->product_variant_id ] = $_variant->product_variant_id;
  372 + foreach ($this->variants ?: [] as $_variant) {
  373 + $todel[$_variant->product_variant_id] = $_variant->product_variant_id;
369 374 }
370   - foreach($this->_variants as $_variant) {
371   - if(!is_array($_variant)) {
  375 + foreach ($this->_variants as $_variant) {
  376 + if (!is_array($_variant)) {
372 377 return;
373 378 }
374   - if(!empty( $_variant[ 'product_variant_id' ] )) {
375   - unset( $todel[ $_variant[ 'product_variant_id' ] ] );
376   - $model = ProductVariant::findOne($_variant[ 'product_variant_id' ]);
  379 + if (!empty($_variant['product_variant_id'])) {
  380 + unset($todel[$_variant['product_variant_id']]);
  381 + $model = ProductVariant::findOne($_variant['product_variant_id']);
377 382 } else {
378 383 $model = new ProductVariant();
379 384 }
380   - $_variant[ 'product_id' ] = $this->product_id;
381   - $model->load([ 'ProductVariant' => $_variant ]);
  385 + $_variant['product_id'] = $this->product_id;
  386 + $model->load(['ProductVariant' => $_variant]);
382 387 $model->product_id = $this->product_id;
383 388 $model->save();
384 389 }
385   - if(!empty( $todel )) {
386   - ProductVariant::deleteAll([ 'product_variant_id' => $todel ]);
  390 + if (!empty($todel)) {
  391 + ProductVariant::deleteAll(['product_variant_id' => $todel]);
387 392 }
388 393 }
389 394 }
... ...
common/modules/product/models/ProductVariant.php
... ... @@ -333,15 +333,29 @@
333 333 ->where([ 'tax_group_to_category.category_id' => $categories ])
334 334 ->where([ 'level' => $level ]);
335 335 }
336   -
  336 +
337 337 public function afterSave($insert, $changedAttributes)
338 338 {
339   - parent::afterSave($insert, $changedAttributes);
340   - $this->unlinkAll('options', true);
341   - $options = TaxOption::findAll($this->options);
342   - foreach($options as $option) {
343   - $this->link('options', $option);
  339 +
  340 + if(!empty($this->_options)){
  341 + $options = TaxOption::findAll($this->_options);
  342 + $this->unlinkAll('options',true);
  343 + foreach($options as $option){
  344 + $this->link('options', $option);
  345 + }
344 346 }
  347 +
  348 +
  349 + if (!empty($this->stocks)) {
  350 + ProductStock::deleteAll(['product_variant_id' => $this->product_variant_id]);
  351 + $values = [];
  352 + foreach ($this->stocks as $id => $quantity) {
  353 + $productStock = ProductStock::find()->where(['product_variant_id' => $this->product_variant_id, 'stock_id' => $id])->one();
  354 + $productStock->quantity = $quantity;
  355 + $productStock->save();
  356 + }
  357 + }
  358 + parent::afterSave($insert, $changedAttributes);
345 359 }
346 360  
347 361 public function imagesUpload()
... ...
common/modules/product/views/manage/import-process.php
1 1 <?php
2   -
3   -use yii\helpers\Html;
4   -use yii\widgets\ActiveForm;
5   -
6 2 $this->registerJs("
7   -
8   -");
9   -?>
10   -
11   -<script type="text/javascript">
12   - jQuery(document).ready(function () {
13   - var in_process=false;
  3 +var in_process=false;
14 4 var count=1;
15 5  
16 6 in_process=true;
... ... @@ -21,7 +11,7 @@ $this-&gt;registerJs(&quot;
21 11 from = typeof(from) != 'undefined' ? from : 0;
22 12 console.log('go', from);
23 13 $.ajax({
24   - url: "<?= Yii::$app->request->baseUrl .'/product/manage/'. $method?>",
  14 + url: '".\Yii::$app->request->baseUrl .'/product/manage/'. $method."',
25 15 data: {from:from},
26 16 dataType: 'json',
27 17 success: function(data){
... ... @@ -46,13 +36,11 @@ $this-&gt;registerJs(&quot;
46 36 }
47 37 },
48 38 error: function(xhr, status, errorThrown) {
49   - alert(errorThrown+'\n'+xhr.responseText);
50 39 }
51 40 });
52 41 }
53   -
54   - });
55   -</script>
  42 +");
  43 +//?>
56 44  
57 45 <div class="product-import-process-form">
58 46 <h1>Импорт <?= $method == 'prices' ? 'цен' : 'данных'?> товаров</h1>
... ...
common/modules/product/views/manage/import.php
1 1 <?php
  2 +
  3 + /**
  4 + * @var Import $model
  5 + * @var array $languages
  6 + */
  7 +
  8 + use common\modules\product\models\Import;
  9 + use yii\helpers\Html;
  10 + use yii\widgets\ActiveForm;
2 11  
3   -use yii\helpers\Html;
4   -use yii\widgets\ActiveForm;
5 12 ?>
6 13  
7 14 <div class="product-import-form">
8 15 <?php $form = ActiveForm::begin([
9 16 'enableClientValidation' => false,
10   - 'options' => ['enctype' => 'multipart/form-data']
  17 + 'options' => [ 'enctype' => 'multipart/form-data' ],
11 18 ]); ?>
12   -
13   - <?php if($model->errors) :?>
14   - <div class="error">
15   - <?= implode("<br>\n", $model->errors);?>
16   - </div>
17   - <?php endif?>
18   -
19   - <?php if($model->output) :?>
  19 +
  20 + <?php if($model->errors) : ?>
  21 + <div class="error">
  22 + <?= implode("<br>\n", $model->errors); ?>
  23 + </div>
  24 + <?php endif ?>
  25 +
  26 + <?php if($model->output) : ?>
20 27 <h2>Лог операции</h2>
21   - <div class="success" style="height: 10em;overflow: auto;border: 1px solid #000">
22   - <?= implode("<br>\n", $model->output);?>
23   - </div>
24   - <?php endif?>
25   -
26   - <?= $form->field($model, 'type')->radioList([
27   - 'products' => Yii::t('product', 'Load products'),
28   - 'prices' => Yii::t('product', 'Load prices'),
29   - ]);?>
30   -
31   - <?= $form->field($model, 'file')->fileInput(['multiple' => false,])?>
32   -
  28 + <div class="success" style="height: 10em;overflow: auto;border: 1px solid #000">
  29 + <?= implode("<br>\n", $model->output); ?>
  30 + </div>
  31 + <?php endif ?>
  32 +
  33 + <?= $form->field($model, 'type')
  34 + ->radioList([
  35 + 'products' => Yii::t('product', 'Load products'),
  36 + 'prices' => Yii::t('product', 'Load prices'),
  37 + ]); ?>
  38 +
  39 + <?= $form->field($model, 'lang')
  40 + ->dropDownList($languages); ?>
  41 +
  42 + <?= $form->field($model, 'file')
  43 + ->fileInput([ 'multiple' => false, ]) ?>
  44 +
33 45 <?php /*= $form->field($model, 'file')->widget(\kartik\file\FileInput::classname(), [
34 46 'language' => 'ru',
35 47 'options' => [
... ... @@ -41,11 +53,11 @@ use yii\widgets\ActiveForm;
41 53 'showRemove' => false,
42 54 'showUpload' => false,
43 55 ],
44   - ])*/?>
45   -
  56 + ])*/ ?>
  57 +
46 58 <div class="form-group">
47   - <?= Html::submitButton(Yii::t('product', 'Import'), ['class' => 'btn btn-primary']) ?>
  59 + <?= Html::submitButton(Yii::t('product', 'Import'), [ 'class' => 'btn btn-primary' ]) ?>
48 60 </div>
49   -
  61 +
50 62 <?php ActiveForm::end(); ?>
51 63 </div>
... ...
common/modules/rubrication/models/TaxOption.php
... ... @@ -63,10 +63,10 @@
63 63 ],
64 64 ],
65 65 ],
66   - 'artboxtree' => [
67   - 'class' => ArtboxTreeBehavior::className(),
68   - 'keyNameGroup' => 'tax_group_id',
69   - ],
  66 +// 'artboxtree' => [
  67 +// 'class' => ArtboxTreeBehavior::className(),
  68 +// 'keyNameGroup' => 'tax_group_id',
  69 +// ],
70 70 'language' => [
71 71 'class' => LanguageBehavior::className(),
72 72 ],
... ...
console/controllers/ImportController.php
... ... @@ -20,15 +20,15 @@ class ImportController extends Controller {
20 20 }
21 21  
22 22 public function actionProducts() {
23   - if (file_exists(Yii::getAlias('@uploadDir/goProducts.lock'))) {
24   - $this->errors[] = 'Task already executed';
25   - return Controller::EXIT_CODE_ERROR;
26   - }
27   - $ff = fopen(Yii::getAlias('@uploadDir/goProducts.lock'), 'w+');
28   - fclose($ff);
  23 +// if (file_exists(Yii::getAlias('@uploadDir/goProducts.lock'))) {
  24 +// $this->errors[] = 'Task already executed';
  25 +// return Controller::EXIT_CODE_ERROR;
  26 +// }
  27 +// $ff = fopen(Yii::getAlias('@uploadDir/goProducts.lock'), 'w+');
  28 +// fclose($ff);
29 29 $model = new Import();
30 30 $model->goProducts(0, null);
31   - unlink(Yii::getAlias('@uploadDir/goProducts.lock'));
  31 +// unlink(Yii::getAlias('@uploadDir/goProducts.lock'));
32 32 return Controller::EXIT_CODE_NORMAL;
33 33 }
34 34  
... ...
console/migrations/m161011_104931_create_stock_lang_table.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +/**
  6 + * Handles the creation for table `stock_lang`.
  7 + */
  8 +class m161011_104931_create_stock_lang_table extends Migration
  9 +{
  10 + /**
  11 + * @inheritdoc
  12 + */
  13 + public function up()
  14 + {
  15 + $this->createTable('stock_lang', [
  16 + 'stock_id' => $this->integer()
  17 + ->notNull(),
  18 + 'language_id' => $this->integer()
  19 + ->notNull(),
  20 + 'name' => $this->string()
  21 + ->notNull(),
  22 + ]);
  23 + $this->createIndex('stock_lang_stock_language_key', 'stock_lang', [
  24 + 'stock_id',
  25 + 'language_id',
  26 + ], true);
  27 +
  28 + $this->addForeignKey('stock_fk', 'stock_lang', 'stock_id', 'stock', 'stock_id', 'CASCADE', 'CASCADE');
  29 + $this->addForeignKey('language_fk', 'stock_lang', 'language_id', 'language', 'language_id', 'RESTRICT', 'CASCADE');
  30 + }
  31 +
  32 + /**
  33 + * @inheritdoc
  34 + */
  35 + public function down()
  36 + {
  37 + $this->dropTable('stock_lang');
  38 + }
  39 +}
... ...