Commit 5ee9ab1fc09bb421a9966f606916a245f6f78700
1 parent
8724ec1f
-
Showing
12 changed files
with
454 additions
and
22 deletions
Show diff stats
backend/config/bootstrap.php
| 1 | 1 | <?php |
| 2 | 2 | Yii::setAlias('@uploadDir', dirname(dirname(__DIR__)) . '/storage/sync'); |
| 3 | 3 | Yii::setAlias('@uploadFileProducts', 'products.csv'); |
| 4 | +Yii::setAlias('@uploadFilePrices', 'prices.csv'); | |
| 5 | +Yii::setAlias('@uploadFilePricesAway', 'price_product_away.csv'); | |
| 6 | +Yii::setAlias('@uploadFilePricesDuplicate', 'price_duplicate.csv'); | |
| 7 | +Yii::setAlias('@uploadFilePricesNoVariant', 'price_no_variant.csv'); | |
| 4 | 8 | |
| 5 | 9 | Yii::setAlias('@productsDir', '@frontend/web/images/products'); |
| 6 | 10 | \ No newline at end of file | ... | ... |
common/modules/product/controllers/ManageController.php
| ... | ... | @@ -264,12 +264,15 @@ class ManageController extends Controller |
| 264 | 264 | public function actionImport() { |
| 265 | 265 | $model = new Import(); |
| 266 | 266 | |
| 267 | - if (Yii::$app->request->isPost) { | |
| 267 | + if ($model->load(Yii::$app->request->post())) { | |
| 268 | 268 | $file = UploadedFile::getInstances($model, 'file'); |
| 269 | - if (!empty($file[0]) && $model->validate() && $file[0]->saveAs(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'))) { | |
| 270 | - $model->go(); | |
| 269 | + $method = 'go'. ucfirst($model->type); | |
| 270 | + if (!empty($file) && $model->validate()) { | |
| 271 | + $file[0]->saveAs(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFile'. ucfirst($model->type))); | |
| 272 | + $model->$method(); | |
| 271 | 273 | } |
| 272 | 274 | } |
| 275 | + | |
| 273 | 276 | return $this->render('import', [ |
| 274 | 277 | 'model' => $model, |
| 275 | 278 | ]); | ... | ... |
common/modules/product/models/Product.php
| ... | ... | @@ -188,6 +188,10 @@ class Product extends \yii\db\ActiveRecord |
| 188 | 188 | return $this->getRelations('product_option'); |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | + public function getStocks() { | |
| 192 | + return $this->hasMany(Stock::className(), ['stock_id' => 'stock_id'])->viaTable(ProductStock::tableName(), ['product_id' => 'product_id']); | |
| 193 | + } | |
| 194 | + | |
| 191 | 195 | /** |
| 192 | 196 | * @inheritdoc |
| 193 | 197 | * @return ProductQuery the active query used by this AR class. | ... | ... |
| 1 | +<?php | |
| 2 | + | |
| 3 | +namespace common\modules\product\models; | |
| 4 | + | |
| 5 | +use Yii; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * This is the model class for table "product_stock". | |
| 9 | + * | |
| 10 | + * @property integer $product_id | |
| 11 | + * @property integer $stock_id | |
| 12 | + * @property integer $quantity | |
| 13 | + * @property integer $product_variant_id | |
| 14 | + * | |
| 15 | + * @property Product $product | |
| 16 | + * @property ProductVariant $productVariant | |
| 17 | + * @property Stock $stock | |
| 18 | + */ | |
| 19 | +class ProductStock extends \yii\db\ActiveRecord | |
| 20 | +{ | |
| 21 | + /** | |
| 22 | + * @inheritdoc | |
| 23 | + */ | |
| 24 | + public static function tableName() | |
| 25 | + { | |
| 26 | + return 'product_stock'; | |
| 27 | + } | |
| 28 | + | |
| 29 | + /** | |
| 30 | + * @inheritdoc | |
| 31 | + */ | |
| 32 | + public function rules() | |
| 33 | + { | |
| 34 | + return [ | |
| 35 | + [['product_id', 'stock_id', 'quantity', 'product_variant_id'], 'integer'], | |
| 36 | + [['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['product_id' => 'product_id']], | |
| 37 | + [['product_variant_id'], 'exist', 'skipOnError' => true, 'targetClass' => ProductVariant::className(), 'targetAttribute' => ['product_variant_id' => 'product_variant_id']], | |
| 38 | + [['stock_id'], 'exist', 'skipOnError' => true, 'targetClass' => Stock::className(), 'targetAttribute' => ['stock_id' => 'stock_id']], | |
| 39 | + ]; | |
| 40 | + } | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * @inheritdoc | |
| 44 | + */ | |
| 45 | + public function attributeLabels() | |
| 46 | + { | |
| 47 | + return [ | |
| 48 | + 'product_id' => 'Product ID', | |
| 49 | + 'stock_id' => 'Stock ID', | |
| 50 | + 'quantity' => 'Quantity', | |
| 51 | + 'product_variant_id' => 'Product Variant ID', | |
| 52 | + ]; | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * @return \yii\db\ActiveQuery | |
| 57 | + */ | |
| 58 | + public function getProduct() | |
| 59 | + { | |
| 60 | + return $this->hasOne(Product::className(), ['product_id' => 'product_id']); | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * @return \yii\db\ActiveQuery | |
| 65 | + */ | |
| 66 | + public function getProductVariant() | |
| 67 | + { | |
| 68 | + return $this->hasOne(ProductVariant::className(), ['product_variant_id' => 'product_variant_id']); | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * @return \yii\db\ActiveQuery | |
| 73 | + */ | |
| 74 | + public function getStock() | |
| 75 | + { | |
| 76 | + return $this->hasOne(Stock::className(), ['stock_id' => 'stock_id']); | |
| 77 | + } | |
| 78 | +} | ... | ... |
common/modules/product/models/ProductVariant.php
| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | namespace common\modules\product\models; |
| 4 | 4 | |
| 5 | 5 | use Yii; |
| 6 | +use yii\helpers\ArrayHelper; | |
| 6 | 7 | |
| 7 | 8 | /** |
| 8 | 9 | * This is the model class for table "product_variant". |
| ... | ... | @@ -33,6 +34,7 @@ class ProductVariant extends \yii\db\ActiveRecord |
| 33 | 34 | public $translit; |
| 34 | 35 | public $translit_rubric; |
| 35 | 36 | private $data; |
| 37 | + public $stocks = []; | |
| 36 | 38 | |
| 37 | 39 | /** @var array $_images */ |
| 38 | 40 | // public $imagesUpload = []; |
| ... | ... | @@ -106,8 +108,12 @@ class ProductVariant extends \yii\db\ActiveRecord |
| 106 | 108 | return $this->hasOne(Product::className(), ['product_id' => 'product_id']); |
| 107 | 109 | } |
| 108 | 110 | |
| 109 | - public function getEnabled() { | |
| 110 | - return $this->stock !== 0; | |
| 111 | + public function getQuantity() { | |
| 112 | + return ProductStock::find() | |
| 113 | + ->where(['product_variant_id' => $this->product_variant_id]) | |
| 114 | + ->sum('quantity'); | |
| 115 | +// return $this->hasMany(Stock::className(), ['stock_id' => 'stock_id'])->viaTable(ProductStock::tableName(), ['product_id' => 'product_id'])->sum(ProductStock::tableName() .'.quantity') > 0; | |
| 116 | +// return $this->stock !== 0; | |
| 111 | 117 | } |
| 112 | 118 | |
| 113 | 119 | public function getStock_caption() { |
| ... | ... | @@ -157,7 +163,36 @@ class ProductVariant extends \yii\db\ActiveRecord |
| 157 | 163 | return $this->product_variant_id; |
| 158 | 164 | } |
| 159 | 165 | |
| 166 | + public function setStocks($stocks) { | |
| 167 | + $this->stocks = (array) $stocks; | |
| 168 | + } | |
| 169 | + | |
| 170 | + /*public function getStocks() { | |
| 171 | + return $this->hasMany(Stock::className(), ['stock_id' => 'stock_id'])->viaTable(ProductStock::tableName(), ['product_variant_id' => 'product_variant_id']); | |
| 172 | + } | |
| 173 | + | |
| 174 | + public function getStocksIds() { | |
| 175 | + return ArrayHelper::getColumn($this->hasMany(Stock::className(), ['stock_id' => 'stock_id'])->viaTable(ProductStock::tableName(), ['product_variant_id' => 'product_variant_id'])->all(), 'stock_id'); | |
| 176 | + }*/ | |
| 177 | + | |
| 178 | + public function afterSave($insert, $changedAttributes) | |
| 179 | + { | |
| 180 | + if (!empty($this->stocks)) { | |
| 181 | + ProductStock::deleteAll(['product_variant_id' => $this->product_variant_id]); | |
| 182 | + $values = []; | |
| 183 | + foreach ($this->stocks as $id => $quantity) { | |
| 184 | + $values[] = [$this->product_id, $this->product_variant_id, $id, $quantity]; | |
| 185 | + } | |
| 186 | + if ($values) { | |
| 187 | + self::getDb()->createCommand() | |
| 188 | + ->batchInsert(ProductStock::tableName(), ['product_id', 'product_variant_id', 'stock_id', 'quantity'], $values)->execute(); | |
| 189 | + } | |
| 190 | + } | |
| 191 | + parent::afterSave($insert, $changedAttributes); | |
| 192 | + } | |
| 193 | + | |
| 160 | 194 | public function beforeDelete() { |
| 161 | 195 | ProductImage::deleteAll(['product_variant_id' => $this->product_variant_id]); |
| 196 | + ProductStock::deleteAll(['product_variant_id' => $this->product_variant_id]); | |
| 162 | 197 | } |
| 163 | 198 | } | ... | ... |
| 1 | +<?php | |
| 2 | + | |
| 3 | +namespace common\modules\product\models; | |
| 4 | + | |
| 5 | +use Yii; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * This is the model class for table "stock". | |
| 9 | + * | |
| 10 | + * @property integer $stock_id | |
| 11 | + * @property string $name | |
| 12 | + * | |
| 13 | + * @property ProductStock[] $productStocks | |
| 14 | + */ | |
| 15 | +class Stock extends \yii\db\ActiveRecord | |
| 16 | +{ | |
| 17 | + /** | |
| 18 | + * @inheritdoc | |
| 19 | + */ | |
| 20 | + public static function tableName() | |
| 21 | + { | |
| 22 | + return 'stock'; | |
| 23 | + } | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * @inheritdoc | |
| 27 | + */ | |
| 28 | + public function rules() | |
| 29 | + { | |
| 30 | + return [ | |
| 31 | + [['name'], 'string', 'max' => 150], | |
| 32 | + ]; | |
| 33 | + } | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * @inheritdoc | |
| 37 | + */ | |
| 38 | + public function attributeLabels() | |
| 39 | + { | |
| 40 | + return [ | |
| 41 | + 'stock_id' => Yii::t('product', 'Stock ID'), | |
| 42 | + 'name' => Yii::t('product', 'Name'), | |
| 43 | + ]; | |
| 44 | + } | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * @inheritdoc | |
| 48 | + * @return StockQuery the active query used by this AR class. | |
| 49 | + */ | |
| 50 | + public static function find() | |
| 51 | + { | |
| 52 | + return new StockQuery(get_called_class()); | |
| 53 | + } | |
| 54 | +} | ... | ... |
| 1 | +<?php | |
| 2 | + | |
| 3 | +namespace common\modules\product\models; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * This is the ActiveQuery class for [[Stock]]. | |
| 7 | + * | |
| 8 | + * @see Stock | |
| 9 | + */ | |
| 10 | +class StockQuery extends \yii\db\ActiveQuery | |
| 11 | +{ | |
| 12 | + /*public function active() | |
| 13 | + { | |
| 14 | + return $this->andWhere('[[status]]=1'); | |
| 15 | + }*/ | |
| 16 | + | |
| 17 | + /** | |
| 18 | + * @inheritdoc | |
| 19 | + * @return Stock[]|array | |
| 20 | + */ | |
| 21 | + public function all($db = null) | |
| 22 | + { | |
| 23 | + return parent::all($db); | |
| 24 | + } | |
| 25 | + | |
| 26 | + /** | |
| 27 | + * @inheritdoc | |
| 28 | + * @return Stock|array|null | |
| 29 | + */ | |
| 30 | + public function one($db = null) | |
| 31 | + { | |
| 32 | + return parent::one($db); | |
| 33 | + } | |
| 34 | +} | ... | ... |
common/modules/product/models/import.php
| ... | ... | @@ -18,6 +18,7 @@ use yii\base\Model; |
| 18 | 18 | |
| 19 | 19 | class Import extends Model { |
| 20 | 20 | public $file; |
| 21 | + public $type; | |
| 21 | 22 | |
| 22 | 23 | public $errors = []; |
| 23 | 24 | public $output = []; |
| ... | ... | @@ -28,8 +29,10 @@ class Import extends Model { |
| 28 | 29 | public function rules() |
| 29 | 30 | { |
| 30 | 31 | return [ |
| 31 | -// [['file'], 'safe'], | |
| 32 | - [['file'], 'file'], | |
| 32 | + [['type'], 'required'], | |
| 33 | + [['type'], 'string'], | |
| 34 | + [['file'], 'safe'], | |
| 35 | + [['file'], 'file', 'extensions' => 'csv'], | |
| 33 | 36 | ]; |
| 34 | 37 | } |
| 35 | 38 | |
| ... | ... | @@ -43,13 +46,18 @@ class Import extends Model { |
| 43 | 46 | ]; |
| 44 | 47 | } |
| 45 | 48 | |
| 46 | - public function go() { | |
| 49 | + public function getType() { | |
| 50 | + if (!$this->type) { | |
| 51 | + $this->type = 'products'; | |
| 52 | + } | |
| 53 | + return $this->type; | |
| 54 | + } | |
| 47 | 55 | |
| 56 | + public function goProducts() { | |
| 57 | + set_time_limit(0); | |
| 48 | 58 | $new_products = $linked_products = 0; |
| 49 | 59 | |
| 50 | - $db = yii::$app->db; | |
| 51 | - | |
| 52 | - if ( !($handle = $this->getProductsFile()) ) { | |
| 60 | + if ( !($handle = $this->getProductsFile('uploadFileProducts')) ) { | |
| 53 | 61 | $this->errors[] = 'File not found'; |
| 54 | 62 | return FALSE; |
| 55 | 63 | } |
| ... | ... | @@ -351,12 +359,108 @@ class Import extends Model { |
| 351 | 359 | return TRUE; |
| 352 | 360 | } |
| 353 | 361 | |
| 354 | - private function getProductsFile() { | |
| 355 | - $filename = Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'); | |
| 362 | + public function goPrices() { | |
| 363 | + set_time_limit(0); | |
| 364 | + $new_products = $linked_products = 0; | |
| 365 | + | |
| 366 | + if ( !($handle = $this->getProductsFile('uploadFilePrices')) ) { | |
| 367 | + $this->errors[] = 'File not found'; | |
| 368 | + return FALSE; | |
| 369 | + } | |
| 370 | + | |
| 371 | + $j = 0; | |
| 372 | + | |
| 373 | + while (($data = fgetcsv ($handle, 10000, ";")) !== FALSE) { | |
| 374 | + $j++; | |
| 375 | +// if ($j > 10) { | |
| 376 | +// return TRUE; | |
| 377 | +// } | |
| 378 | + | |
| 379 | + foreach ($data as &$value) | |
| 380 | + { | |
| 381 | + //$value = mb_convert_encoding ($value, "UTF-8", mb_detect_encoding ($value)); | |
| 382 | + $value = iconv ('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); | |
| 383 | + $value = trim ($value); | |
| 384 | + } | |
| 385 | + | |
| 386 | + // данные строк | |
| 387 | + $modification_code = @$data[0]; | |
| 388 | + $price = floatval(@$data[1]); | |
| 389 | + $price_promo = floatval(@$data[2]); | |
| 390 | + $count = intval(@$data[3]); | |
| 391 | + $city_name = @$data[4]; | |
| 392 | + $product_title = @$data[5]; | |
| 393 | + | |
| 394 | + if (empty ($modification_code)) { | |
| 395 | + CONTINUE; | |
| 396 | + } | |
| 397 | + // товары в пути | |
| 398 | + if (empty ($city_name)) | |
| 399 | + { | |
| 400 | + $this->saveNotFoundRecord ( | |
| 401 | + [$modification_code, $product_title], | |
| 402 | + Yii::getAlias('@uploadFilePricesAway') | |
| 403 | + ); | |
| 404 | + | |
| 405 | + $this->output[] = 'Товар '. $product_title . ' в пути'; | |
| 406 | + | |
| 407 | + CONTINUE; | |
| 408 | + } | |
| 409 | + | |
| 410 | + if ( ($productVariant = ProductVariant::find()->filterWhere(['ilike', 'sku', trim($modification_code)])->one()) === null ) { | |
| 411 | + // 'Нет даной модификации в базе'; | |
| 412 | + $this->saveNotFoundRecord ( | |
| 413 | + [$modification_code, $product_title], | |
| 414 | + Yii::getAlias('@uploadFilePricesNoVariant') | |
| 415 | + ); | |
| 416 | + | |
| 417 | + $this->output[] = 'Для товара '. $product_title . ' не найдено соотвествия'; | |
| 418 | + | |
| 419 | + CONTINUE; | |
| 420 | + } | |
| 421 | + | |
| 422 | + $quantity = 0; | |
| 423 | + | |
| 424 | + // ===== Set stock ==== | |
| 425 | + if ( $city_name ) { | |
| 426 | + if ( ($stock = Stock::find()->filterWhere(['ilike', 'name', trim($city_name)])->one()) === null ) { | |
| 427 | + // Create stock | |
| 428 | + $stock = new Stock(); | |
| 429 | + $stock->name = trim($city_name); | |
| 430 | + $stock->save(); | |
| 431 | + } | |
| 432 | + | |
| 433 | + $productVariant->stocks[$stock->stock_id] = $count; | |
| 434 | + $quantity = $quantity + $count; | |
| 435 | + } | |
| 436 | + | |
| 437 | + $productVariant->price = $price; | |
| 438 | + $productVariant->price_old = $price_promo; | |
| 439 | + $productVariant->stock = $quantity; | |
| 440 | + | |
| 441 | + $productVariant->save(); | |
| 442 | + | |
| 443 | + $this->output[] = '<font style="color:blue">Товар '. $product_title .' успешно сохранен</font>'; | |
| 444 | + } | |
| 445 | + fclose ($handle); | |
| 446 | + } | |
| 447 | + | |
| 448 | + private function getProductsFile($file_type) { | |
| 449 | + $filename = Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@'. $file_type); | |
| 356 | 450 | if (!is_file($filename)) { |
| 357 | - $this->stderr("File $filename not found"); | |
| 451 | + $this->errors[] = "File $filename not found"; | |
| 358 | 452 | return FALSE; |
| 359 | 453 | } |
| 360 | 454 | return fopen ($filename, 'r'); |
| 361 | 455 | } |
| 456 | + | |
| 457 | + private function saveNotFoundRecord (array $line, $filename) | |
| 458 | + { | |
| 459 | + $str = implode (';', $line)."\n"; | |
| 460 | + $str = iconv ("UTF-8//TRANSLIT//IGNORE", "windows-1251", $str); | |
| 461 | + | |
| 462 | + $fg = fopen (Yii::getAlias('@uploadDir') .'/'. $filename, 'a+'); | |
| 463 | + fputs ($fg, $str); | |
| 464 | + fclose ($fg); | |
| 465 | + } | |
| 362 | 466 | } |
| 363 | 467 | \ No newline at end of file | ... | ... |
common/modules/product/views/manage/import.php
| ... | ... | @@ -6,6 +6,7 @@ use yii\widgets\ActiveForm; |
| 6 | 6 | |
| 7 | 7 | <div class="product-import-form"> |
| 8 | 8 | <?php $form = ActiveForm::begin([ |
| 9 | + 'enableClientValidation' => false, | |
| 9 | 10 | 'options' => ['enctype' => 'multipart/form-data'] |
| 10 | 11 | ]); ?> |
| 11 | 12 | |
| ... | ... | @@ -16,12 +17,20 @@ use yii\widgets\ActiveForm; |
| 16 | 17 | <?php endif?> |
| 17 | 18 | |
| 18 | 19 | <?php if($model->output) :?> |
| 19 | - <div class="success"> | |
| 20 | + <h2>Лог операции</h2> | |
| 21 | + <div class="success" style="height: 10em;overflow: auto;border: 1px solid #000"> | |
| 20 | 22 | <?= implode("<br>\n", $model->output);?> |
| 21 | 23 | </div> |
| 22 | 24 | <?php endif?> |
| 23 | 25 | |
| 24 | - <?= $form->field($model, 'file')->widget(\kartik\file\FileInput::classname(), [ | |
| 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 | + | |
| 33 | + <?php /*= $form->field($model, 'file')->widget(\kartik\file\FileInput::classname(), [ | |
| 25 | 34 | 'language' => 'ru', |
| 26 | 35 | 'options' => [ |
| 27 | 36 | 'multiple' => false, |
| ... | ... | @@ -32,7 +41,7 @@ use yii\widgets\ActiveForm; |
| 32 | 41 | 'showRemove' => false, |
| 33 | 42 | 'showUpload' => false, |
| 34 | 43 | ], |
| 35 | - ])?> | |
| 44 | + ])*/?> | |
| 36 | 45 | |
| 37 | 46 | <div class="form-group"> |
| 38 | 47 | <?= Html::submitButton(Yii::t('product', 'Import'), ['class' => 'btn btn-primary']) ?> | ... | ... |
console/config/bootstrap.php
| 1 | 1 | <?php |
| 2 | 2 | Yii::setAlias('@uploadDir', dirname(dirname(__DIR__)) . '/storage/sync'); |
| 3 | 3 | Yii::setAlias('@uploadFileProducts', 'products.csv'); |
| 4 | +Yii::setAlias('@uploadFilePrices', 'prices.csv'); | |
| 5 | +Yii::setAlias('@uploadFilePricesAway', 'price_product_away.csv'); | |
| 6 | +Yii::setAlias('@uploadFilePricesDuplicate', 'price_duplicate.csv'); | |
| 7 | +Yii::setAlias('@uploadFilePricesNoVariant', 'price_no_variant.csv'); | |
| 4 | 8 | |
| 5 | -Yii::setAlias('@productsDir', '@frontend/web/images/products'); | |
| 9 | +Yii::setAlias('@productsDir', '@frontend/web/images/products'); | |
| 6 | 10 | \ No newline at end of file | ... | ... |
console/controllers/ImportController.php
| ... | ... | @@ -6,6 +6,7 @@ use common\modules\product\models\Category; |
| 6 | 6 | use common\modules\product\models\CategoryName; |
| 7 | 7 | use common\modules\product\models\ProductImage; |
| 8 | 8 | use common\modules\product\models\ProductVariantType; |
| 9 | +use common\modules\product\models\Stock; | |
| 9 | 10 | use common\modules\rubrication\models\TaxOption; |
| 10 | 11 | use common\modules\rubrication\models\TaxValueString; |
| 11 | 12 | use Yii; |
| ... | ... | @@ -18,8 +19,8 @@ use yii\console\Controller; |
| 18 | 19 | use yii\helpers\Console; |
| 19 | 20 | |
| 20 | 21 | class ImportController extends Controller { |
| 21 | - private function getProductsFile() { | |
| 22 | - $filename = Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFileProducts'); | |
| 22 | + private function getProductsFile($file_type = 'uploadFileProducts') { | |
| 23 | + $filename = Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@'. $file_type); | |
| 23 | 24 | if (!is_file($filename)) { |
| 24 | 25 | $this->stderr("File $filename not found"); |
| 25 | 26 | return FALSE; |
| ... | ... | @@ -402,4 +403,103 @@ class ImportController extends Controller { |
| 402 | 403 | public function goProducts() { |
| 403 | 404 | |
| 404 | 405 | } |
| 406 | + | |
| 407 | + public function actionPrices() { | |
| 408 | + $new_products = $linked_products = 0; | |
| 409 | + | |
| 410 | + if ( !($handle = $this->getProductsFile('uploadFilePrices')) ) { | |
| 411 | + $this->stdout("File not found\n"); | |
| 412 | + return Controller::EXIT_CODE_ERROR; | |
| 413 | + } | |
| 414 | + | |
| 415 | + $j = 0; | |
| 416 | + | |
| 417 | + while (($data = fgetcsv ($handle, 10000, ";")) !== FALSE) { | |
| 418 | + $j++; | |
| 419 | +// if ($j > 10) { | |
| 420 | +// return TRUE; | |
| 421 | +// } | |
| 422 | + | |
| 423 | + foreach ($data as &$value) | |
| 424 | + { | |
| 425 | + //$value = mb_convert_encoding ($value, "UTF-8", mb_detect_encoding ($value)); | |
| 426 | + $value = iconv ('windows-1251', "UTF-8//TRANSLIT//IGNORE", $value); | |
| 427 | + $value = trim ($value); | |
| 428 | + } | |
| 429 | + | |
| 430 | + // данные строк | |
| 431 | + $modification_code = @$data[0]; | |
| 432 | + $price = floatval(@$data[1]); | |
| 433 | + $price_promo = floatval(@$data[2]); | |
| 434 | + $count = intval(@$data[3]); | |
| 435 | + $city_name = @$data[4]; | |
| 436 | + $product_title = @$data[5]; | |
| 437 | + | |
| 438 | + if (empty ($modification_code)) { | |
| 439 | + CONTINUE; | |
| 440 | + } | |
| 441 | + // товары в пути | |
| 442 | + if (empty ($city_name)) | |
| 443 | + { | |
| 444 | + $this->saveNotFoundRecord ( | |
| 445 | + [$modification_code, $product_title], | |
| 446 | + Yii::getAlias('@uploadFilePricesAway') | |
| 447 | + ); | |
| 448 | + | |
| 449 | +// $this->stdout("Товар $product_title в пути\n"); | |
| 450 | + | |
| 451 | + CONTINUE; | |
| 452 | + } | |
| 453 | + | |
| 454 | + if ( ($productVariant = ProductVariant::find()->filterWhere(['ilike', 'sku', trim($modification_code)])->one()) === null ) { | |
| 455 | + // 'Нет даной модификации в базе'; | |
| 456 | + $this->saveNotFoundRecord ( | |
| 457 | + [$modification_code, $product_title], | |
| 458 | + Yii::getAlias('@uploadFilePricesNoVariant') | |
| 459 | + ); | |
| 460 | + | |
| 461 | +// $this->stdout("Для товара $product_title (#$modification_code) не найдено соотвествия\n"); | |
| 462 | + | |
| 463 | + CONTINUE; | |
| 464 | + } | |
| 465 | + | |
| 466 | + $quantity = 0; | |
| 467 | + | |
| 468 | + // ===== Set stock ==== | |
| 469 | + if ( $city_name ) { | |
| 470 | + if ( ($stock = Stock::find()->filterWhere(['ilike', 'name', trim($city_name)])->one()) === null ) { | |
| 471 | + // Create stock | |
| 472 | + $stock = new Stock(); | |
| 473 | + $stock->name = trim($city_name); | |
| 474 | + $stock->save(); | |
| 475 | + } | |
| 476 | + | |
| 477 | + $productVariant->stocks[$stock->stock_id] = $count; | |
| 478 | + $quantity = $quantity + $count; | |
| 479 | + } | |
| 480 | + | |
| 481 | + $productVariant->price = $price; | |
| 482 | + $productVariant->price_old = $price_promo; | |
| 483 | + $productVariant->stock = $quantity; | |
| 484 | + | |
| 485 | + $productVariant->save(); | |
| 486 | + | |
| 487 | +// $this->stdout("Товар $product_title успешно сохранен\n"); | |
| 488 | + } | |
| 489 | + fclose ($handle); | |
| 490 | + | |
| 491 | + unlink(Yii::getAlias('@uploadDir') .'/'. Yii::getAlias('@uploadFilePrices')); | |
| 492 | + | |
| 493 | + return Controller::EXIT_CODE_NORMAL; | |
| 494 | + } | |
| 495 | + | |
| 496 | + private function saveNotFoundRecord (array $line, $filename) | |
| 497 | + { | |
| 498 | + $str = implode (';', $line)."\n"; | |
| 499 | + $str = iconv ("UTF-8//TRANSLIT//IGNORE", "windows-1251", $str); | |
| 500 | + | |
| 501 | + $fg = fopen (Yii::getAlias('@uploadDir') .'/'. $filename, 'a+'); | |
| 502 | + fputs ($fg, $str); | |
| 503 | + fclose ($fg); | |
| 504 | + } | |
| 405 | 505 | } |
| 406 | 506 | \ No newline at end of file | ... | ... |
frontend/views/catalog/product.php
| ... | ... | @@ -96,8 +96,8 @@ $this->registerJs (" |
| 96 | 96 | <h1><?= $product->fullname ?></h1> |
| 97 | 97 | <div class="begin">Цветовые решения</div> |
| 98 | 98 | <ul class="product_mod"> |
| 99 | - <?php foreach (array_reverse($product->variants) as $variant): ?> | |
| 100 | - <?php if (!is_null($variant->stock) && empty($variant->stock)) continue;?> | |
| 99 | + <?php foreach ($product->variants as $variant): ?> | |
| 100 | + <?php if ($variant->quantity > 0) continue;?> | |
| 101 | 101 | <li> |
| 102 | 102 | <a id='m<?= $variant->product_variant_id ?>' href="#<?=$variant->product_variant_id ?>" |
| 103 | 103 | data-cost="<?= $variant->price ?>" |
| ... | ... | @@ -107,6 +107,9 @@ $this->registerJs (" |
| 107 | 107 | data-imageoriginal="<?= $variant->imageUrl ?>" |
| 108 | 108 | title="<?= $product->fullname ?>"> |
| 109 | 109 | <?= \common\components\artboximage\ArtboxImageHelper::getImage($variant->imageUrl, 'product_variant')?> |
| 110 | + <?php | |
| 111 | + var_dump($variant->quantity); | |
| 112 | + ?> | |
| 110 | 113 | </a> |
| 111 | 114 | </li> |
| 112 | 115 | <?php endforeach; ?> | ... | ... |