Commit 166dd085afd8890d3dfc5a959163582a5b25e0f8

Authored by Administrator
2 parents e556dca5 c4da20f0

Merge remote-tracking branch 'origin/master'

Showing 51 changed files with 2436 additions and 415 deletions   Show diff stats
1 .idea 1 .idea
2 -/uploads  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +/uploads
  4 +/vendor
4 \ No newline at end of file 5 \ No newline at end of file
backend/components/base/BaseActiveRecord.php
@@ -9,4 +9,17 @@ @@ -9,4 +9,17 @@
9 namespace backend\components\base; 9 namespace backend\components\base;
10 10
11 11
12 -class BaseActiveRecord extends \yii\db\ActiveRecord {}  
13 \ No newline at end of file 12 \ No newline at end of file
  13 +use yii\base\ErrorException;
  14 +
  15 +class BaseActiveRecord extends \yii\db\ActiveRecord {
  16 +
  17 + public function throwStringErrorException(){
  18 +
  19 + $errors_str = '';
  20 + foreach ($this->getErrors() as $error) {
  21 + $errors_str .= implode( array_values($error) );
  22 + }
  23 + throw new ErrorException( $errors_str );
  24 + }
  25 +
  26 +}
14 \ No newline at end of file 27 \ No newline at end of file
backend/components/parsers/CustomConverter.php 0 → 100644
  1 +<?php
  2 +namespace backend\components\parsers;
  3 +use yii\multiparser\Converter;
  4 +
  5 +class CustomConverter extends Converter {
  6 +
  7 + /**
  8 + * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи
  9 + * @param $key_array - ключи для вложенного массива
  10 + * @return array - таблица с проименованными колонками
  11 + */
  12 + public static function convertToAssocArray ( array $value_arr, array $key_array, $key_prefix = '')
  13 + {
  14 + // очистка служебного префикса в массиве заголовков
  15 + if ($key_prefix) {
  16 + $params_array = array_fill( 0, count($key_array), $key_prefix );
  17 + //@todo переписать с использованием array_walk
  18 + $key_array = array_map( function ($value, $key_prefix){ return str_replace( $key_prefix, '',$value ); }, $key_array, $params_array );
  19 + //уберем пустые элементы
  20 + $key_array = array_filter($key_array, function ($value){ return $value !==''; });
  21 + }
  22 +
  23 + // преобразуем массив ключей (обернем в массив), для передачи его в качестве параметра в анонимную функцию для array_map
  24 + // для этого увеличим размерность массива, что бы при каждом обходе массива $value_arr , функции был доступен исходный массив ключей
  25 + $key_array = array_fill( 0, count($value_arr), $key_array );
  26 + // \common\components\CustomVarDamp::dumpAndDie($key_array);
  27 + $result = array_map(
  28 + function ($value, $key_array) {
  29 + $res = $value;
  30 + foreach ($value as $key => $sub_value) {
  31 + if (isset($key_array[$key])) {
  32 + // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим
  33 + $new_key = $key_array[$key];
  34 + if( !array_key_exists( $new_key , $res ) ){
  35 + $res[ $new_key ] = $res[$key];
  36 + }
  37 + }
  38 + unset( $res[$key] );
  39 + }
  40 +
  41 + return $res;
  42 + },
  43 + $value_arr, $key_array);
  44 + return $result;
  45 + }
  46 +
  47 + /**
  48 + * @param $value_arr - двумерный массив к которому нужно добавить колонки
  49 + * @param $add_array - массив с колонками (ключи) и занчениями колонок
  50 + * @return mixed
  51 + */
  52 + public function addColumns ( array $value_arr , array $add_array )
  53 + {
  54 + $i = 0;
  55 + while ($i < count($value_arr)) {
  56 + foreach ($add_array as $add_key => $add_value) {
  57 + $value_arr[$i][$add_key] = $add_value;
  58 + }
  59 + $i++;
  60 + }
  61 + return $value_arr;
  62 + }
  63 +}
0 \ No newline at end of file 64 \ No newline at end of file
backend/components/parsers/config.php 0 → 100644
  1 +<?php
  2 + return [
  3 + 'global' =>
  4 + ['ini' => ['upload_max_filesize' => '20M',
  5 + 'post_max_size integer' => '30M',
  6 + ]],
  7 + 'csv' =>
  8 + ['web' =>
  9 + ['class' => 'backend\components\parsers\CustomCsvParser',
  10 + 'auto_detect_first_line' => true,
  11 + 'converter_conf' => ['class' => ' backend\components\parsers\CustomConverter',
  12 + 'configuration' => ["string" => 'DESCR'],]
  13 + ],
  14 +
  15 + 'basic_column' => [
  16 + Null => 'Пусто',
  17 + "BRAND" => 'Бренд',
  18 + "ARTICLE"=> 'Артикул',
  19 + "PRICE" => 'Цена',
  20 + "DESCR" => 'Наименование',
  21 + "BOX" => 'Колво',
  22 + "ADD_BOX"=> 'В пути',
  23 + "GROUP" => 'Группа RG'
  24 + ],
  25 + ],
  26 + 'xml' =>
  27 + ['web' =>
  28 + ['class' => 'yii\multiparser\XmlParser',
  29 + 'node' => 'Товар',],
  30 +
  31 + 'basic_column' => [
  32 + "BRAND" => 'Производитель',
  33 + "ARTICLE"=> 'Код',
  34 + "PRICE" => 'Розница',
  35 + "DESCR" => 'Наименование',
  36 + "BOX" => 'Колво',
  37 + "ADD_BOX"=> 'Ожидаемое',
  38 + "GROUP" => 'Группа'
  39 + ],
  40 + ]
  41 + ];
  42 +
  43 +
  44 +//[
  45 +// "float" => 'PRICE',
  46 +// "integer" => ['BOX' , 'ADD_BOX' ],
  47 +// "prefix" => 'ARTICLE'
  48 +//]
0 \ No newline at end of file 49 \ No newline at end of file
backend/controllers/CartController.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace backend\controllers;
  4 +
  5 +use Yii;
  6 +use common\models\CartBillsView;
  7 +use common\models\CartBillsSearch;
  8 +use backend\components\base\BaseController;
  9 +use yii\web\NotFoundHttpException;
  10 +use yii\filters\VerbFilter;
  11 +
  12 +/**
  13 + * CartController implements the CRUD actions for CartBills model.
  14 + */
  15 +class CartController extends BaseController
  16 +{
  17 + public $layout = "/column";
  18 +
  19 + /**
  20 + * Lists all CartBills models.
  21 + * @return mixed
  22 + */
  23 + public function actionIndex()
  24 + {
  25 + $searchModel = new CartBillsSearch();
  26 + $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
  27 +
  28 + return $this->render('index', [
  29 + 'searchModel' => $searchModel,
  30 + 'dataProvider' => $dataProvider,
  31 + ]);
  32 + }
  33 +
  34 + /**
  35 + * Displays a single CartBills model.
  36 + * @param string $id
  37 + * @return mixed
  38 + */
  39 + public function actionView($id)
  40 + {
  41 + return $this->render('view', [
  42 + 'model' => $this->findModel($id),
  43 + ]);
  44 + }
  45 +
  46 +
  47 + /**
  48 + * Finds the CartBills model based on its primary key value.
  49 + * If the model is not found, a 404 HTTP exception will be thrown.
  50 + * @param string $id
  51 + * @return CartBills the loaded model
  52 + * @throws NotFoundHttpException if the model cannot be found
  53 + */
  54 + protected function findModel($id)
  55 + {
  56 + if (($model = CartBillsView::findById($id)) !== null) {
  57 + return $model;
  58 + } else {
  59 + throw new NotFoundHttpException('The requested page does not exist.');
  60 + }
  61 + }
  62 +}
backend/controllers/ParserController.php
1 <?php 1 <?php
2 namespace backend\controllers; 2 namespace backend\controllers;
3 3
  4 +use common\components\archives\ArchiveCreator;
  5 +use common\components\mail\ImapMailReader;
  6 +use common\components\mail\MailAttachmentsSaver;
  7 +use common\components\parsers\MailParser;
4 use Yii; 8 use Yii;
5 use yii\data\ActiveDataProvider; 9 use yii\data\ActiveDataProvider;
6 use yii\filters\AccessControl; 10 use yii\filters\AccessControl;
@@ -15,6 +19,7 @@ use backend\models\Importers; @@ -15,6 +19,7 @@ use backend\models\Importers;
15 use yii\base\ErrorException; 19 use yii\base\ErrorException;
16 use common\components\PriceWriter; 20 use common\components\PriceWriter;
17 use common\components\CustomVarDamp; 21 use common\components\CustomVarDamp;
  22 +use common\components\CustomArrayHelper;
18 23
19 /** 24 /**
20 * Parser controller 25 * Parser controller
@@ -51,10 +56,10 @@ class ParserController extends BaseController @@ -51,10 +56,10 @@ class ParserController extends BaseController
51 56
52 public function actionIndex($mode = 0) 57 public function actionIndex($mode = 0)
53 { 58 {
  59 + $this->mailTest();
54 $model = new UploadFileParsingForm(); 60 $model = new UploadFileParsingForm();
55 // установим режим, 0 - ручная загрузка, 1 - автозагрузка 61 // установим режим, 0 - ручная загрузка, 1 - автозагрузка
56 $model->mode = $mode; 62 $model->mode = $mode;
57 - //CustomVarDamp::dumpAndDie(phpinfo());  
58 return $this->render('index', ['model' => $model]); 63 return $this->render('index', ['model' => $model]);
59 } 64 }
60 65
@@ -81,7 +86,6 @@ class ParserController extends BaseController @@ -81,7 +86,6 @@ class ParserController extends BaseController
81 try { 86 try {
82 $files_model->save(); 87 $files_model->save();
83 } catch (ErrorException $e) { 88 } catch (ErrorException $e) {
84 - // CustomVarDamp::dump($e->getMessage());  
85 throw $e; 89 throw $e;
86 } 90 }
87 // получим id только что записанной записи - его запишем в название файла 91 // получим id только что записанной записи - его запишем в название файла
@@ -125,11 +129,12 @@ class ParserController extends BaseController @@ -125,11 +129,12 @@ class ParserController extends BaseController
125 129
126 } else { 130 } else {
127 // не прошла валидация форма загрузки файлов 131 // не прошла валидация форма загрузки файлов
128 - $errors_str = '';  
129 - foreach ($model->getErrors() as $error) {  
130 - $errors_str .= implode( array_values($error) );  
131 - }  
132 - throw new ErrorException( $errors_str ); 132 +// $errors_str = '';
  133 +// foreach ($model->getErrors() as $error) {
  134 +// $errors_str .= implode( array_values($error) );
  135 +// }
  136 +// throw new ErrorException( $errors_str );
  137 + $model->throwStringErrorException();
133 } 138 }
134 // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные 139 // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
135 } else if (Yii::$app->getCache()->get('parser_data')) { 140 } else if (Yii::$app->getCache()->get('parser_data')) {
@@ -145,7 +150,6 @@ class ParserController extends BaseController @@ -145,7 +150,6 @@ class ParserController extends BaseController
145 ], 150 ],
146 ]); 151 ]);
147 152
148 -  
149 $last_index = end( array_flip( $data[0] ) ); 153 $last_index = end( array_flip( $data[0] ) );
150 $header_counts = $last_index + 1; 154 $header_counts = $last_index + 1;
151 //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список) 155 //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список)
@@ -186,7 +190,7 @@ class ParserController extends BaseController @@ -186,7 +190,7 @@ class ParserController extends BaseController
186 190
187 // соотнесем отпарсенные данные с соответсивем полученным от пользователя 191 // соотнесем отпарсенные данные с соответсивем полученным от пользователя
188 // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию 192 // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
189 - $data = \Yii::$app->multiparser->convertToAssocArray($data, $arr , 'attr_'); 193 + $data = CustomArrayHelper::createAssocArray( $data, $arr , 'attr_' );
190 194
191 // запустим специальный класс который запишет данные в таблицы связанные с прайсами 195 // запустим специальный класс который запишет данные в таблицы связанные с прайсами
192 $writer = new PriceWriter(); 196 $writer = new PriceWriter();
@@ -287,5 +291,71 @@ class ParserController extends BaseController @@ -287,5 +291,71 @@ class ParserController extends BaseController
287 // $csv->actionParseCsv(); 291 // $csv->actionParseCsv();
288 } 292 }
289 293
  294 + private function mailTest(){
  295 +
  296 + $mail_reader = new ImapMailReader( '{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000' );
  297 + $mailboxes = $mail_reader->getListMailboxes();
  298 + $files = [];
  299 + foreach ( $mailboxes as $custom_label ) {
  300 + $words = explode(" ",str_replace( array($mail_reader->getHostname(),"!"),"",imap_utf7_decode($custom_label)) );
  301 + $importer_id = (int)preg_replace("/[^A-Z0-9]+/","", strtoupper($words[0]));
  302 +
  303 + $mail_reader->reOpen( $custom_label );
  304 + $saver = new MailAttachmentsSaver( $mail_reader );
  305 + if ( $importer_id ) {
  306 + $saver->setFileNamePrefix( $importer_id . '~!~' );
  307 + }
  308 +
  309 + if( $saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'), 'UNSEEN') ){
  310 + $files = array_merge( $files, $saver->getSavedFilesArr() );
  311 + }else{
  312 + continue;
  313 + }
  314 +
  315 + }
  316 +
  317 + if ( !$files ) {
  318 + return;
  319 + }
  320 +
  321 + $arch_creator = new ArchiveCreator();
  322 + $arch_extensions = $arch_creator->getHandleExtension();
  323 + $arch_files = array_intersect( $files , $arch_extensions );
  324 + foreach ($arch_files as $arch_name => $arch_ext) {
  325 + $arch_reader = $arch_creator->create( $arch_name, $arch_ext );
  326 + $arch_reader->extractTo(\Yii::getAlias('@temp_upload'));
  327 + unset( $files[$arch_name] );
  328 + $files = array_merge( $files, $arch_reader->getExtractedFiles());
  329 + }
  330 +
  331 + $new_destination = \Yii::getAlias('@auto_upload') . '/';
  332 + foreach ( $files as $name => $ext ) {
  333 +
  334 + $file_name = pathinfo($name, PATHINFO_FILENAME) . '.' . $ext;
  335 + if( $ext = 'csv' ){
  336 + $files_model = new ImportersFiles();
  337 + $files_model->importer_id = $importer_id;
  338 + if ($files_model->save()) {
  339 +
  340 + $file_name = \Yii::$app->db->getLastInsertID() . '.csv';
  341 +
  342 + } else{
  343 +
  344 + $files_model->throwStringErrorException();
  345 + }
  346 +
  347 + }
  348 + $new_destination .= $file_name;
  349 + if( rename( $name, $new_destination ) ){
  350 +
  351 + CustomVarDamp::dump('1111111');
  352 +
  353 + } else{
  354 + new \ErrorException("Нет возможности переписать файл {$name}");
  355 + }
  356 +
  357 + }
  358 +
  359 + }
290 360
291 } 361 }
backend/controllers/RgGrupController.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 27.10.2015
  6 + * Time: 15:22
  7 + */
  8 +
  9 +namespace backend\controllers;
  10 +
  11 +use backend\components\base\BaseController;
  12 +use backend\models\UploadFileRgForm;
  13 +use common\components\CustomVarDamp;
  14 +use common\components\parsers\MailAttachmentsSaver;
  15 +use common\models\Margins;
  16 +use common\models\MarginsGroups;
  17 +use yii\filters\AccessControl;
  18 +use Yii;
  19 +use yii\web\UploadedFile;
  20 +use yii\data\ArrayDataProvider;
  21 +use yii\multiparser\DynamicFormHelper;
  22 +use common\components\CustomArrayHelper;
  23 +
  24 +class RgGrupController extends BaseController
  25 +{
  26 + public $layout = "/column";
  27 +
  28 + /**
  29 + * @inheritdoc
  30 + */
  31 + public function behaviors()
  32 + {
  33 + return [
  34 + 'access' => [
  35 + 'class' => AccessControl::className(),
  36 + 'rules' => [
  37 + [
  38 + 'allow' => true,
  39 + 'roles' => ['@'],
  40 + ],
  41 + ],
  42 + ],
  43 +// 'verbs' => [
  44 +// 'class' => VerbFilter::className(),
  45 +// 'actions' => [
  46 +// 'logout' => ['post'],
  47 +// ],
  48 +// ],
  49 + ];
  50 + }
  51 +
  52 + public function actionIndex()
  53 + {
  54 + $model = new UploadFileRgForm();
  55 +
  56 + return $this->render('index', ['model' => $model]);
  57 + }
  58 +
  59 + public function actionResults()
  60 + {
  61 + $model = new UploadFileRgForm();
  62 + $data = [];
  63 +
  64 + if ($model->load(Yii::$app->request->post())) {
  65 + $model->file = UploadedFile::getInstance($model, 'file');
  66 + // первый проход - валидируем, сохраняем файл, ложим в кеш отпарсенные данные и параметры модели (потом при записи в базу данных они пригодятся)
  67 + if ($model->validate()) {
  68 +
  69 + $model->file_path = Yii::getAlias('@manual_upload') . '/' . $model->file->name;
  70 + $model->file->saveAs($model->file_path);
  71 +
  72 + //запускаем парсинг
  73 + $data = $model->readFile();
  74 + // сохраняем в кеш отпарсенные даные
  75 + Yii::$app->getCache()->set('parser_data', json_encode($data));
  76 + // сохраняем в кеш модель - в ней настройки для дальнейшей обработки данных
  77 + Yii::$app->getCache()->set('parser_configuration', serialize($model));
  78 +
  79 +
  80 + } else {
  81 + // не прошла валидация форма загрузки файлов
  82 + $errors_str = '';
  83 + foreach ($model->getErrors() as $error) {
  84 + $errors_str .= implode(array_values($error));
  85 + }
  86 + throw new \ErrorException($errors_str);
  87 + }
  88 + // листаем пагинатором, или повторно вызываем - считываем из кеша отпрасенные данные
  89 + } else if (Yii::$app->getCache()->get('parser_data')) {
  90 +
  91 + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true);
  92 +
  93 + }
  94 + $provider = new ArrayDataProvider([
  95 + 'allModels' => $data,
  96 + 'pagination' => [
  97 + 'pageSize' => 10,
  98 + ],
  99 + ]);
  100 + // создадим модель на столько реквизитов сколько колонок в отпарсенном файле
  101 + $last_index = end(array_flip($data[0]));
  102 + $header_counts = $last_index + 1;
  103 + $header_model = DynamicFormHelper::CreateDynamicModel($header_counts);
  104 +
  105 + // соберем массив данных из которых будет пользователь выбирать значения в конструкторе (выпадающий список)
  106 + $header_array = Margins::getHeader();
  107 +
  108 + return $this->render('results',
  109 + ['model' => $data,
  110 + 'header_model' => $header_model,
  111 + // список колонок для выбора
  112 + 'basic_column' => $header_array,
  113 + 'dataProvider' => $provider]);
  114 + }
  115 +
  116 + public function actionWrite()
  117 + {
  118 + //получим колонки которые выбрал пользователь
  119 + $arr_attributes = Yii::$app->request->post()['DynamicModel'];
  120 + //соберем модель по полученным данным
  121 + $model = DynamicFormHelper::CreateDynamicModel($arr_attributes);
  122 + //добавим правила валидации (колонки должны быть те что в модели)
  123 + foreach ($arr_attributes as $key => $value) {
  124 + $model->addRule($key, 'in', ['range' => array_keys(Margins::getHeader())]);
  125 + }
  126 +
  127 + // провалидируем выбранные колонки
  128 + if ($model->validate()) {
  129 +
  130 + // валидация успешна у нас есть соответсвие колонок, преобразуем в массив данное соответсвие для дальнейшей работы
  131 + $arr = $model->toArray();
  132 +
  133 + // получим данные из кеша
  134 + if (Yii::$app->getCache()->get('parser_data') && Yii::$app->getCache()->get('parser_configuration')) {
  135 + $data = json_decode(Yii::$app->getCache()->get('parser_data'), true);
  136 + $configuration = unserialize(Yii::$app->getCache()->get('parser_configuration'));
  137 + } else {
  138 + throw new \ErrorException('Ошибка кеша');
  139 + }
  140 +
  141 + array_walk($arr, function (&$val) {
  142 + $val = '!' . $val;
  143 + });
  144 +
  145 + // соотнесем отпарсенные данные с соответсивем полученным от пользователя
  146 + // для этого преобразуем массив отпарсенных данных - назначим ключи согласно соответствию
  147 + $data = CustomArrayHelper::createAssocArray($data, $arr, 'attr_');
  148 +
  149 + // в первой строке у нас заголовки - уберем
  150 + unset($data[0]);
  151 + // подготовим данные для записи в таблицу w_margins_groups
  152 + $arr_values = [];
  153 + $group = '';
  154 + $importer_id = $configuration['importer_id'];
  155 + foreach ($data as $row_data) {
  156 +
  157 + if (isset($row_data['!group'])) {
  158 + $group = $row_data['!group'];
  159 + unset($row_data['!group']);
  160 + }
  161 + if (isset($row_data['!_null'])) {
  162 + unset($row_data['!_null']);
  163 + }
  164 +
  165 + foreach ($row_data as $key => $value) {
  166 + if ($group)
  167 + $row['group'] = trim($group);
  168 +
  169 + $row['importer_id'] = trim($importer_id);
  170 + $row['margin_id'] = ltrim($key, '!');
  171 + $row['koef'] = \Yii::$app->converter->convertTo('float', $value);
  172 +
  173 + $arr_values[] = $row;
  174 +
  175 + }
  176 +
  177 + }
  178 + // сохраним подготовленные данные
  179 + MarginsGroups::ManualInsertWithUpdate( $arr_values, [ 'group','importer_id','margin_id' ] );
  180 +
  181 +
  182 + Yii::$app->session->setFlash('success', "Файл {$configuration['file']} успешно загружен");
  183 + // все прошло успешно - очищаем кеш
  184 + Yii::$app->getCache()->delete('parser_data');
  185 + Yii::$app->getCache()->delete('parser_configuration');
  186 +
  187 + if (file_exists($configuration['file_path']))
  188 + unlink($configuration['file_path']);
  189 +
  190 + return $this->render('index', ['model' => $configuration]);
  191 +
  192 + }
  193 +
  194 + }
  195 +
  196 + public function actionMail()
  197 + {
  198 + $mail_saver = new MailAttachmentsSaver('{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000');
  199 + //$mail_saver = new MailAttachmentsSaver('{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'price@italauto.com.ua', '67853562');
  200 + $mail_saver->saveAttachmentsTo();
  201 + }
  202 +
  203 +}
backend/models/Details.php
@@ -36,6 +36,7 @@ class Details extends BaseActiveRecord @@ -36,6 +36,7 @@ class Details extends BaseActiveRecord
36 /** 36 /**
37 * @var bool - признак необходимости удалить префикс Артикула перед вставкой 37 * @var bool - признак необходимости удалить префикс Артикула перед вставкой
38 */ 38 */
  39 +
39 public $delete_price = false; 40 public $delete_price = false;
40 41
41 /** 42 /**
@@ -131,6 +132,9 @@ class Details extends BaseActiveRecord @@ -131,6 +132,9 @@ class Details extends BaseActiveRecord
131 132
132 //воспользуемся пакетной вставкой от фреймворка 133 //воспользуемся пакетной вставкой от фреймворка
133 $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;
  135 + if ($this->delete_prefix) {
  136 + $query_insert = $this->prepareArticul( $query_insert );
  137 + }
134 // добавим фрагмент с апдейтом при дубляже 138 // добавим фрагмент с апдейтом при дубляже
135 $query = "{$query_insert} {$query_update}"; 139 $query = "{$query_insert} {$query_update}";
136 // \common\components\CustomVarDamp::dumpAndDie($query); 140 // \common\components\CustomVarDamp::dumpAndDie($query);
@@ -138,4 +142,5 @@ class Details extends BaseActiveRecord @@ -138,4 +142,5 @@ class Details extends BaseActiveRecord
138 142
139 } 143 }
140 } 144 }
  145 +
141 } 146 }
backend/models/UploadFileParsingForm.php
@@ -48,7 +48,7 @@ class UploadFileParsingForm extends Model @@ -48,7 +48,7 @@ class UploadFileParsingForm extends Model
48 return [ 48 return [
49 ['importer_id', 'required', 'message' => 'Не указан поставщик!' ], 49 ['importer_id', 'required', 'message' => 'Не указан поставщик!' ],
50 ['file', 'required', 'message' => 'Не выбран файл!' ], 50 ['file', 'required', 'message' => 'Не выбран файл!' ],
51 - [['file'], 'file', 'extensions' => ['csv', 'xml'], 'checkExtensionByMimeType'=>false ], 51 + [['file'], 'file', 'extensions' => ['csv', 'xlsx'], 'checkExtensionByMimeType'=>false ],
52 ['importer_id', 'integer','max' => 999999, 'min' => 0 ], 52 ['importer_id', 'integer','max' => 999999, 'min' => 0 ],
53 [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки 53 [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки
54 ['delimiter', 'string', 'max' => 1], 54 ['delimiter', 'string', 'max' => 1],
@@ -71,12 +71,15 @@ class UploadFileParsingForm extends Model @@ -71,12 +71,15 @@ class UploadFileParsingForm extends Model
71 public function readFile( $options = [] ){ 71 public function readFile( $options = [] ){
72 72
73 $data = Yii::$app->multiparser->parse( $this->file_path, $options ); 73 $data = Yii::$app->multiparser->parse( $this->file_path, $options );
74 - if( !is_array( $data ) ){ 74 +
  75 + if( !is_array( $data ) || count($data) == 0 ){
75 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}"); 76 throw new ErrorException("Ошибка чтения из файла прайса {$this->file_path}");
76 } 77 }
77 // файл больше не нужен - данные прочитаны и сохранены в кеш 78 // файл больше не нужен - данные прочитаны и сохранены в кеш
78 - if( file_exists($this->file_path) )  
79 - unlink($this->file_path); 79 + if( file_exists($this->file_path) )
  80 + //@ todo - перестало работать - нет доступа на удалениев этом сеансе, в следующем - файл удаляется - разобраться
  81 + //unlink( $this->file_path );
  82 +
80 83
81 return $data; 84 return $data;
82 } 85 }
backend/models/UploadFileRgForm.php 0 → 100644
  1 +<?php
  2 +namespace backend\models;
  3 +
  4 +use yii\base\ErrorException;
  5 +use yii\base\Model;
  6 +use yii\web\UploadedFile;
  7 +use Yii;
  8 +use common\components\CustomVarDamp;
  9 +
  10 +/**
  11 + * UploadForm is the model behind the upload form.
  12 + */
  13 +class UploadFileRgForm extends Model
  14 +{
  15 + /**
  16 + * @var UploadedFile file attribute
  17 + */
  18 + // атрибуты формы
  19 + public $file;
  20 + public $file_path;
  21 + public $importer_id;
  22 +
  23 +
  24 +
  25 + public function rules()
  26 + {
  27 + return [
  28 + ['file', 'required', 'message' => 'Не выбран файл!' ],
  29 + ['importer_id', 'required', 'message' => 'Не указан поставщик!' ],
  30 + [['file'], 'file', 'extensions' => 'xlsx', 'checkExtensionByMimeType'=>false ]
  31 + ];
  32 + }
  33 +
  34 + public function attributeLabels()
  35 + {
  36 + return [
  37 + 'file' => Yii::t('app', 'Источник'),
  38 + 'importer_id' => Yii::t('app', 'Поставщик'),
  39 + ];
  40 + }
  41 +
  42 + public function readFile( $options = [] ){
  43 +
  44 + $data = Yii::$app->multiparser->parse( $this->file_path, $options );
  45 + if( !is_array( $data ) ){
  46 + throw new ErrorException("Ошибка чтения из файла RG групп {$this->file_path}");
  47 + }
  48 +
  49 +
  50 + return $data;
  51 + }
  52 +
  53 + function __destruct()
  54 + {
  55 + // файл больше не нужен - данные прочитаны и сохранены в кеш
  56 + // if( file_exists($this->file_path) )
  57 + // unlink($this->file_path);
  58 + }
  59 +
  60 +
  61 +}
0 \ No newline at end of file 62 \ No newline at end of file
backend/views/cart/_form.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\CartBills */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="cart-bills-form">
  12 +
  13 + <?php $form = ActiveForm::begin(); ?>
  14 +
  15 + <?= $form->field($model, 'account_id')->textInput(['maxlength' => true]) ?>
  16 +
  17 + <?= $form->field($model, 'manager_id')->textInput(['maxlength' => true]) ?>
  18 +
  19 + <?= $form->field($model, 'office_id')->textInput(['maxlength' => true]) ?>
  20 +
  21 + <?= $form->field($model, 'status')->textInput(['maxlength' => true]) ?>
  22 +
  23 + <?= $form->field($model, 'f1')->textInput(['maxlength' => true]) ?>
  24 +
  25 + <?= $form->field($model, 'f2')->textInput(['maxlength' => true]) ?>
  26 +
  27 + <?= $form->field($model, 'f3')->textInput(['maxlength' => true]) ?>
  28 +
  29 + <?= $form->field($model, 'message')->textarea(['rows' => 6]) ?>
  30 +
  31 + <?= $form->field($model, 'safe_bill')->textInput() ?>
  32 +
  33 + <?= $form->field($model, 'delivery')->textInput(['maxlength' => true]) ?>
  34 +
  35 + <?= $form->field($model, 'delivery_price')->textInput() ?>
  36 +
  37 + <?= $form->field($model, 'timestamp')->textInput() ?>
  38 +
  39 + <div class="form-group">
  40 + <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  41 + </div>
  42 +
  43 + <?php ActiveForm::end(); ?>
  44 +
  45 +</div>
backend/views/cart/_search.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\ActiveForm;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\CartBillsSearch */
  8 +/* @var $form yii\widgets\ActiveForm */
  9 +?>
  10 +
  11 +<div class="cart-bills-search">
  12 +
  13 + <?php $form = ActiveForm::begin([
  14 + 'action' => ['index'],
  15 + 'method' => 'get',
  16 + ]); ?>
  17 +
  18 + <?= $form->field($model, 'id') ?>
  19 +
  20 + <?= $form->field($model, 'account_id') ?>
  21 +
  22 + <?= $form->field($model, 'manager_id') ?>
  23 +
  24 + <?= $form->field($model, 'office_id') ?>
  25 +
  26 + <?= $form->field($model, 'status')->dropDownList(\yii\helpers\ArrayHelper::map( \common\models\DicStatuses::find()->where(['active' =>1])->all(), 'id','name' )) ?>
  27 +
  28 + <?php // echo $form->field($model, 'f1') ?>
  29 +
  30 + <?php // echo $form->field($model, 'f2') ?>
  31 +
  32 + <?php // echo $form->field($model, 'f3') ?>
  33 +
  34 + <?php // echo $form->field($model, 'message') ?>
  35 +
  36 + <?php // echo $form->field($model, 'safe_bill') ?>
  37 +
  38 + <?php // echo $form->field($model, 'delivery') ?>
  39 +
  40 + <?php // echo $form->field($model, 'delivery_price') ?>
  41 +
  42 + <?php // echo $form->field($model, 'timestamp') ?>
  43 +
  44 + <div class="form-group">
  45 + <?= Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
  46 + <?= Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-default']) ?>
  47 + </div>
  48 +
  49 + <?php ActiveForm::end(); ?>
  50 +
  51 +</div>
backend/views/cart/index.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\grid\GridView;
  5 +use kartik\date\DatePicker;
  6 +
  7 +/* @var $this yii\web\View */
  8 +/* @var $searchModel common\models\CartBillsSearch */
  9 +/* @var $dataProvider yii\data\ActiveDataProvider */
  10 +
  11 +$this->title = Yii::t('app', 'Заказы');
  12 +$this->params['breadcrumbs'][] = $this->title;
  13 +
  14 +?>
  15 +<div class="cart-bills-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 + <?php // echo $this->render('_search', ['model' => $searchModel]); ?>
  19 +
  20 +
  21 + <?= GridView::widget([
  22 + 'dataProvider' => $dataProvider,
  23 + 'filterModel' => $searchModel,
  24 + 'columns' => [
  25 + ['class' => 'yii\grid\SerialColumn'],
  26 +
  27 + 'id',
  28 + 'account_id',
  29 + ['label' =>'Информация',
  30 + 'value' =>function ($data) {
  31 + $info = $data->scode . ' /n';
  32 + $info .= $data->name;
  33 + return $info;
  34 + },
  35 + ],
  36 + 'sum',
  37 + [
  38 + 'label' =>'Статус',
  39 + 'attribute' => 'status',
  40 + 'filter' => \yii\helpers\ArrayHelper::map( \common\models\DicStatuses::find()->where(['active' =>1])->all(), 'id','name' ),
  41 + ],
  42 + 'manager_name',
  43 + [
  44 + 'label' =>'Дата',
  45 + 'value' =>function ($data) {
  46 + return date('Y-m-d', $data->dt);
  47 + },
  48 + 'attribute' => 'dt',
  49 + 'filter' => DatePicker::widget([
  50 + 'model' =>$searchModel,
  51 + 'language' =>'ru',
  52 + 'size' =>'xs',
  53 + 'separator' =>'по',
  54 + 'attribute' => 'dt',
  55 + 'type' => DatePicker::TYPE_RANGE,
  56 + 'attribute2' => 'date_to',
  57 + ]),
  58 + ],
  59 +
  60 + ],
  61 + ]); ?>
  62 +
  63 +</div>
backend/views/cart/view.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\widgets\DetailView;
  5 +
  6 +/* @var $this yii\web\View */
  7 +/* @var $model common\models\CartBills */
  8 +
  9 +$this->title = $model->id;
  10 +$this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Cart Bills'), 'url' => ['index']];
  11 +$this->params['breadcrumbs'][] = $this->title;
  12 +?>
  13 +<div class="cart-bills-view">
  14 +
  15 + <h1><?= Html::encode($this->title) ?></h1>
  16 +
  17 + <p>
  18 + <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
  19 + <?= Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $model->id], [
  20 + 'class' => 'btn btn-danger',
  21 + 'data' => [
  22 + 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
  23 + 'method' => 'post',
  24 + ],
  25 + ]) ?>
  26 + </p>
  27 +
  28 + <?= DetailView::widget([
  29 + 'model' => $model,
  30 + 'attributes' => [
  31 + 'id',
  32 + 'account_id',
  33 + 'manager_id',
  34 + 'office_id',
  35 + 'status',
  36 + 'f1',
  37 + 'f2',
  38 + 'f3',
  39 + 'message:ntext',
  40 + 'safe_bill',
  41 + 'delivery',
  42 + 'delivery_price',
  43 + 'timestamp',
  44 + ],
  45 + ]) ?>
  46 +
  47 +</div>
backend/views/layouts/column.php
@@ -282,7 +282,10 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;); @@ -282,7 +282,10 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
282 echo Menu::widget([ 282 echo Menu::widget([
283 'options' => ['class' => 'sidebar-menu'], 283 'options' => ['class' => 'sidebar-menu'],
284 'items' => [ 284 'items' => [
  285 + ['label' => 'Заказы', 'url' => ['cart/index']],
285 ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [ 286 ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [
  287 + ['label' => 'Кросс файлы', 'url' => ['crossing-upload/index']],
  288 + ['label' => 'Группы RG', 'url' => ['rg-grup/index']],
286 ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']], 289 ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']],
287 ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]], 290 ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]],
288 ['label' => 'Ручная загрузка', 'url' => ['parser/index']], 291 ['label' => 'Ручная загрузка', 'url' => ['parser/index']],
@@ -317,10 +320,7 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;); @@ -317,10 +320,7 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
317 ['label' => 'Vin коды', 'url' => ['currency/index']], 320 ['label' => 'Vin коды', 'url' => ['currency/index']],
318 ['label' => 'Запросы по номеру', 'url' => ['currency/index']], 321 ['label' => 'Запросы по номеру', 'url' => ['currency/index']],
319 ['label' => 'Офисы', 'url' => ['offices/index']], 322 ['label' => 'Офисы', 'url' => ['offices/index']],
320 - ],  
321 - ],  
322 - ['label' => 'Справочник', 'url' => ['#'], 'items' => [  
323 - ['label' => 'Замены брендов', 'url' => ['currency/index']], 323 + ['label' => 'Валюты', 'url' => ['currency/index']],
324 ], 324 ],
325 ], 325 ],
326 326
backend/views/rg-grup/index.php 0 → 100644
  1 +<?php
  2 +use yii\widgets\ActiveForm;
  3 +use yii\helpers\Html;
  4 +use backend\models\Importers;
  5 +use yii\helpers\ArrayHelper;
  6 +
  7 +$button_label = 'Прочитать';
  8 +
  9 +
  10 +?>
  11 +<div class="row">
  12 + <div class="col-lg-5">
  13 + <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data',],'action'=>['rg-grup/results']]);
  14 +
  15 + if ($msg = \Yii::$app->session->getFlash('success')) { // вернулись после успешной загрузки данного файла
  16 + echo Html::tag('h3', $msg ,['class'=>'bg-success']);
  17 + }
  18 + ?>
  19 + <h3>Загрузка RG групп поставщиков</h3>
  20 +
  21 +
  22 + <?= $form->field($model, 'importer_id')->dropDownList(ArrayHelper::map( Importers::find()->all(), 'id','name' )); ?>
  23 +
  24 +
  25 + <?= $form->field($model, 'file')->fileInput()->label(false) ?>
  26 + <div class="form-group">
  27 + <?= Html::submitButton(Yii::t( 'app', $button_label ), ['class' => 'btn btn-primary']) ?>
  28 + </div>
  29 +
  30 + <?php ActiveForm::end() ?>
  31 + </div>
  32 + <?= Html::a('Почта', ['rg-grup/mail'], ['class' => 'btn btn-primary', 'name' => 'Mail',]) ?>
  33 +</div>
  34 +
backend/views/rg-grup/results.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\helpers\Html;
  4 +use yii\multiparser\DynamicFormHelper;
  5 +use yii\widgets\ActiveForm;
  6 +
  7 +
  8 +/* @var $this yii\web\View */
  9 +/* @var $searchModel backend\models\CatalogSearch */
  10 +/* @var $dataProvider yii\data\ActiveDataProvider */
  11 +
  12 +$this->title = 'Отпарсенные данные файла';
  13 +$this->params['breadcrumbs'][] = $this->title;
  14 +?>
  15 +<div class="catalog-index">
  16 +
  17 + <h1><?= Html::encode($this->title) ?></h1>
  18 + <?php // echo $this->render('_search', ['model' => $searchModel]);
  19 +
  20 +
  21 + $form = ActiveForm::begin(['action' => 'write']);
  22 + ?>
  23 + <?= DynamicFormHelper::CreateGridWithDropDownListHeader( $dataProvider, $form, $header_model, $basic_column )?>
  24 +
  25 + <div class="form-group">
  26 + <?= Html::submitButton(Yii::t('app', 'Записать в БД'), ['class' => 'btn btn-primary']) ?>
  27 + </div>
  28 +
  29 + <?php ActiveForm::end() ?>
  30 + <?= Html::a('Вернуться', ['rg-grup/index'], ['class' => 'btn btn-primary', 'name' => 'Return',]) ?>
  31 +
  32 +</div>
0 \ No newline at end of file 33 \ No newline at end of file
backend/web/.htaccess 0 → 100644
  1 +RewriteEngine on
  2 +
  3 +RewriteBase /
  4 +
  5 +RewriteCond %{REQUEST_FILENAME} !-d
  6 +RewriteCond %{REQUEST_FILENAME} !-f
  7 +
  8 +RewriteRule . index.php
0 \ No newline at end of file 9 \ No newline at end of file
common/components/CustomArrayHelper.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 20.10.2015
  6 + * Time: 14:42
  7 + */
  8 +
  9 +namespace common\components;
  10 +
  11 +
  12 +class CustomArrayHelper extends \yii\helpers\ArrayHelper {
  13 +
  14 + /**
  15 + * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи
  16 + * @param $key_array - ключи для вложенного массива
  17 + * @return array - таблица с проименованными колонками
  18 + */
  19 +
  20 + public static function createAssocArray(array $value_arr, array $key_array, $key_prefix = '')
  21 + {
  22 + // очистка служебного префикса в массиве заголовков
  23 + if ($key_prefix) {
  24 + // @todo оптимизировать - два переворота массива - избыточно
  25 + $key_array = array_flip($key_array);
  26 +
  27 + array_walk($key_array, function (&$value, $key, $key_prefix) {
  28 + $value = str_replace($key_prefix, '', $value);
  29 + }, $key_prefix);
  30 +
  31 + $key_array = array_flip($key_array);
  32 + //уберем пустые элементы
  33 + $key_array = array_filter($key_array, function ($value) {
  34 + return $value !== '';
  35 + });
  36 + }
  37 + array_walk( $value_arr,
  38 +
  39 + function (&$value, $key, $key_array) {
  40 + $res = $value;
  41 + foreach ($res as $sub_key => $sub_value) {
  42 + if (isset($key_array[$sub_key])) {
  43 + // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим
  44 + $new_key = $key_array[$sub_key];
  45 + if (!array_key_exists($new_key, $res)) {
  46 + $res[$new_key] = $value[$sub_key];
  47 + }
  48 + }
  49 + unset($res[$sub_key]);
  50 + $value = $res;
  51 + }
  52 +
  53 + },
  54 +
  55 + $key_array );
  56 +
  57 + return $value_arr;
  58 + }
  59 +
  60 + /**
  61 + * @param $value_arr - двумерный массив к которому нужно добавить колонки
  62 + * @param $add_array - массив с колонками (ключи) и значениями колонок
  63 + * @return mixed
  64 + */
  65 + public static function addColumns(array $value_arr, array $add_array)
  66 + {
  67 + $i = 0;
  68 + while ($i < count($value_arr)) {
  69 + foreach ($add_array as $add_key => $add_value) {
  70 + $value_arr[$i][$add_key] = $add_value;
  71 + }
  72 + $i++;
  73 + }
  74 + return $value_arr;
  75 + }
  76 +}
0 \ No newline at end of file 77 \ No newline at end of file
common/components/PriceWriter.php
@@ -62,20 +62,20 @@ class PriceWriter @@ -62,20 +62,20 @@ class PriceWriter
62 // преобразуем числовые значения 62 // преобразуем числовые значения
63 foreach ($this->data as &$row) { 63 foreach ($this->data as &$row) {
64 64
65 - $row['PRICE'] = \Yii::$app->multiparser->convertToFloat($row['PRICE']);  
66 - $row['BOX'] = \Yii::$app->multiparser->convertToInteger($row['BOX']); 65 + $row['PRICE'] = \Yii::$app->converter->convertTo('float',$row['PRICE']);
  66 + $row['BOX'] = \Yii::$app->converter->convertTo('integer',$row['BOX']);
67 // присвоим полный артикул 67 // присвоим полный артикул
68 68
69 $row['FULL_ARTICLE'] = $row['ARTICLE']; 69 $row['FULL_ARTICLE'] = $row['ARTICLE'];
70 if ((int)$this->configuration['delete_prefix']) { 70 if ((int)$this->configuration['delete_prefix']) {
71 - $row = \Yii::$app->multiparser->convertToArticle( $row, $this->configuration['importer_id'] ); 71 + $row = \Yii::$app->converter->convertTo( 'Article', $row, ['importer_id' => $this->configuration['importer_id']] );
72 } else { 72 } else {
73 - $row['ARTICLE'] = \Yii::$app->multiparser->convertToArticle( $row['ARTICLE'] ); 73 + $row['ARTICLE'] = \Yii::$app->converter->convertTo( 'Article', $row['ARTICLE'] );
74 } 74 }
75 75
76 76
77 if (isset($row['ADD_BOX'])) 77 if (isset($row['ADD_BOX']))
78 - $row['ADD_BOX'] = \Yii::$app->multiparser->convertToInteger($row['ADD_BOX']); 78 + $row['ADD_BOX'] = \Yii::$app->converter->convertTo( 'integer', $row['ADD_BOX'] );
79 79
80 // проверим все ли обязательные колонки были указаны пользователем 80 // проверим все ли обязательные колонки были указаны пользователем
81 $details_model->load(['Details' => $row]); 81 $details_model->load(['Details' => $row]);
@@ -87,11 +87,11 @@ class PriceWriter @@ -87,11 +87,11 @@ class PriceWriter
87 } 87 }
88 88
89 // дополним данные значением импортера и даты обновления цены 89 // дополним данные значением импортера и даты обновления цены
90 - $this->data = \Yii::$app->multiparser->addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); 90 + $this->data = CustomArrayHelper::addColumns( $this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date] );
91 try { 91 try {
92 //@todo add transaction 92 //@todo add transaction
93 93
94 - if ((int)$this->configuration['delete_price']) { 94 + if ( isset($this->configuration['delete_price']) && (int)$this->configuration['delete_price'] ) {
95 $details_model->delete_price = true; 95 $details_model->delete_price = true;
96 } 96 }
97 //2. попытаемся вставить данные в БД с апдейтом по ключам 97 //2. попытаемся вставить данные в БД с апдейтом по ключам
common/components/archives/ArchiveCreator.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 03.11.2015
  6 + * Time: 14:51
  7 + */
  8 +
  9 +namespace common\components\archives;
  10 +
  11 +
  12 +class ArchiveCreator {
  13 +
  14 + protected $handleExtension = ['rar', 'zip'];
  15 +
  16 + public function create( $file, $ext ){
  17 +// if ( $this->isHandleableExtension( $ext )) {
  18 +// $arh_class = ucfirst( $ext ) . 'ArchiveReader';
  19 +// if ( class_exists( $arh_class ) ) {
  20 +//
  21 +// $arh_reader = new $arh_class();
  22 +//
  23 +// if ($arh_reader instanceof ArchiveReader ) {
  24 +// $arh_reader->open($file);
  25 +// return $arh_reader;
  26 +// }
  27 +//
  28 +// }
  29 +//
  30 +// }
  31 + if ( $ext = 'zip' ) {
  32 + $arh_reader = new ZipArchiveReader();
  33 + }else{
  34 + $arh_reader = new RarArchiveReader();
  35 + }
  36 +
  37 + $arh_reader->open($file);
  38 + return $arh_reader;
  39 + // не найден подходящий обработчик
  40 + throw new \Exception( "Для расширения {$ext} не найден подходящий распаковщик" );
  41 + }
  42 +
  43 + protected function isHandleableExtension( $ext ){
  44 +
  45 + // $this->setHandleExtension( );
  46 + return (bool) array_search( $ext, $this->handleExtension);
  47 + }
  48 +
  49 +// protected function setHandleExtension( ){
  50 +// if ( !$this->handleExtension ) {
  51 +// foreach (get_declared_classes() as $class) {
  52 +// if (is_subclass_of( $class, ArchiveReader::class ))
  53 +//
  54 +// $this->handleExtension[] = $class::getExtension();
  55 +//
  56 +// }
  57 +// }
  58 +// }
  59 +
  60 + public function getHandleExtension( ){
  61 +
  62 + // $this->setHandleExtension( );
  63 + return $this->handleExtension;
  64 +
  65 + }
  66 +
  67 +
  68 +}
0 \ No newline at end of file 69 \ No newline at end of file
common/components/archives/ArchiveReader.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 03.11.2015
  6 + * Time: 14:48
  7 + */
  8 +namespace common\components\archives;
  9 +abstract class ArchiveReader
  10 +{
  11 +
  12 + protected $extracted_files = [];
  13 +
  14 + public abstract function open( $file, $password = '');
  15 +
  16 + public abstract function extractTo($destination);
  17 +
  18 + public static abstract function getExtension();
  19 +
  20 + public function getExtractedFiles(){
  21 + return $this->extracted_files;
  22 + }
  23 + public function setExtractedFiles($name, $ext){
  24 + $this->extracted_files[$name] = $ext;
  25 + }
  26 +
  27 +}
0 \ No newline at end of file 28 \ No newline at end of file
common/components/archives/RarArchiveReader.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 03.11.2015
  6 + * Time: 15:12
  7 + */
  8 +
  9 +namespace common\components\archives;
  10 +
  11 +
  12 +class RarArchiveReader extends ArchiveReader {
  13 +
  14 + protected $resource;
  15 + public function open( $file, $password = '' ){
  16 +
  17 + $this->resource = rar_open( $file, $password );
  18 + if ($this->resource === FALSE)
  19 + throw new \Exception("Failed opening rar file");
  20 + }
  21 +
  22 + public function extractTo( $destination){
  23 + $list = rar_list($this->resource);
  24 +
  25 + foreach($list as $file) {
  26 + $entry = rar_entry_get($this->resource, $file);
  27 + $entry->extract($destination);
  28 +
  29 + $this->setExtractedFiles($entry->getName(), pathinfo($entry->getName(), PATHINFO_EXTENSION));
  30 +
  31 + }
  32 +
  33 + rar_close($this->resource);
  34 + }
  35 + public static function getExtension(){
  36 + return 'rar';
  37 + }
  38 +
  39 +
  40 +
  41 +
  42 +}
0 \ No newline at end of file 43 \ No newline at end of file
common/components/archives/ZipArchiveReader.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 03.11.2015
  6 + * Time: 15:12
  7 + */
  8 +
  9 +namespace common\components\archives;
  10 +
  11 +
  12 +class ZipArchiveReader extends ArchiveReader {
  13 +
  14 + protected $resource;
  15 + public function open( $file, $password = '' ){
  16 + $zip = new \ZipArchive;
  17 + $this->resource = $zip->open( $file );
  18 + if ($this->resource === FALSE)
  19 + throw new \Exception("Failed opening zip file");
  20 + }
  21 +
  22 + public function extractTo( $destination){
  23 +
  24 + $this->resource->extractTo($destination);
  25 +
  26 + for ($i = 0; $i < $this->resource->numFiles; $i++) {
  27 + $filename = $this->resource->getNameIndex($i);
  28 + $this->setExtractedFiles($filename, pathinfo($filename, PATHINFO_EXTENSION));
  29 + }
  30 +
  31 + $this->resource->close();
  32 + }
  33 + public static function getExtension(){
  34 + return 'rar';
  35 + }
  36 +
  37 +
  38 +
  39 +
  40 +}
0 \ No newline at end of file 41 \ No newline at end of file
common/components/mail/ImapMailReader.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 02.11.2015
  6 + * Time: 16:56
  7 + */
  8 +
  9 +namespace common\components\mail;
  10 +
  11 +
  12 +class ImapMailReader extends MailReader {
  13 +
  14 + function __construct( $hostname, $username, $password )
  15 + {
  16 + parent::__construct($hostname, $username, $password);
  17 + $this->connection = imap_open($hostname, $username, $password);
  18 +
  19 + if ($this->connection === false)
  20 + throw new \Exception('Cannot connect to mail: ' . imap_last_error());
  21 +
  22 + }
  23 +
  24 + public function getEmails( $flag )
  25 + {
  26 + return imap_search( $this->connection, $flag );
  27 + }
  28 +
  29 + public function getEmailBody( $email_number, $section )
  30 + {
  31 + return imap_fetchbody($this->connection, $email_number, $section );
  32 + }
  33 +
  34 + /**
  35 + * @return mixed
  36 + */
  37 + public function getListMailboxes()
  38 + {
  39 + return imap_list($this->connection, $this->hostname, "*");
  40 + }
  41 +
  42 + public function getCurrentEmailStructure( $email_number )
  43 + {
  44 + return imap_fetchstructure($this->connection, $email_number);
  45 + }
  46 +
  47 + public function reOpen( $hostname )
  48 + {
  49 + imap_reopen( $this->connection, $hostname );
  50 + }
  51 +
  52 + function __destruct()
  53 + {
  54 + /* close the connection */
  55 + imap_close( $this->connection );
  56 + }
  57 +
  58 +
  59 +}
0 \ No newline at end of file 60 \ No newline at end of file
common/components/mail/MailAttachmentsSaver.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Cibermag
  5 + * Date: 01.09.2015
  6 + * Time: 10:53
  7 + */
  8 +
  9 +namespace common\components\mail;
  10 +
  11 +
  12 +use common\components\CustomVarDamp;
  13 +
  14 +/**
  15 + * Class MailAttachmentsSaver
  16 + * @package common\components\mail
  17 + * сохраняет вложения в указанную папку по полученому соединению к ящику,
  18 + * а также хранит имена сохраненных файлов
  19 + */
  20 +class MailAttachmentsSaver
  21 +{
  22 +
  23 + /**
  24 + * @var соединение с ящиком - экземляр класса - MailReader
  25 + */
  26 + protected $mail_reader;
  27 +
  28 + /**
  29 + * @var - string, тип сообщений - например UNSEEN. Значения можно перечислять разделяя запятой.
  30 + */
  31 + protected $massage_type;
  32 +
  33 + /**
  34 + * @var array - после сохранения будет содержать сохраненные файлы, ключ - путь к файлу, значение - расширение
  35 + */
  36 + protected $saved_files_arr;
  37 +
  38 + /**
  39 + * @var - префикс который будет прибавлен к оригинальному имени сохраняемого файла
  40 + */
  41 + protected $file_name_prefix;
  42 +
  43 +
  44 +
  45 + public function __construct(MailReader $mail_reader)
  46 + {
  47 + $this->mail_reader = $mail_reader;
  48 +
  49 + $this->saved_files_arr = [];
  50 +
  51 + }
  52 +
  53 + /**
  54 + * @param mixed $file_name_prefix
  55 + */
  56 + public function setFileNamePrefix($file_name_prefix)
  57 + {
  58 + $this->file_name_prefix = $file_name_prefix;
  59 + }
  60 +
  61 + public function saveAttachmentsTo( $destination, $massage_type )
  62 + {
  63 + $this->massage_type = $massage_type;
  64 + $emails = $this->mail_reader->getEmails($this->massage_type);
  65 +
  66 + /* if emails are returned, cycle through each... */
  67 + $result = false;
  68 + if ($emails) {
  69 +
  70 + /* begin output var */
  71 + $output = '';
  72 +
  73 + /* put the newest emails on top */
  74 + rsort($emails);
  75 + // CustomVarDamp::dump($emails);
  76 + foreach ($emails as $email_number) {
  77 +
  78 + $structure = $this->mail_reader->getCurrentEmailStructure($email_number);
  79 + $attachments = array();
  80 + if (isset($structure->parts) && count($structure->parts)) {
  81 + for ($i = 0; $i < count($structure->parts); $i++) {
  82 + $attachments[$i] = array(
  83 + 'is_attachment' => false,
  84 + 'filename' => '',
  85 + 'name' => '',
  86 + 'attachment' => '');
  87 +
  88 + if ($structure->parts[$i]->ifdparameters) {
  89 + foreach ($structure->parts[$i]->dparameters as $object) {
  90 + if (strtolower($object->attribute) == 'filename') {
  91 + $attachments[$i]['is_attachment'] = true;
  92 + $attachments[$i]['filename'] = $object->value;
  93 + }
  94 + }
  95 + }
  96 +
  97 + if ($structure->parts[$i]->ifparameters) {
  98 + foreach ($structure->parts[$i]->parameters as $object) {
  99 + if (strtolower($object->attribute) == 'name') {
  100 + $attachments[$i]['is_attachment'] = true;
  101 + $attachments[$i]['name'] = $object->value;
  102 + }
  103 + }
  104 + }
  105 +
  106 + if ($attachments[$i]['is_attachment']) {
  107 + $attachments[$i]['attachment'] = $this->mail_reader->getEmailBody($email_number, $i + 1);
  108 + if ($structure->parts[$i]->encoding == 3) { // 3 = BASE64
  109 + $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
  110 + } elseif ($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
  111 + $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
  112 + }
  113 + }
  114 + }
  115 +
  116 + if (count($attachments) != 0) {
  117 +
  118 + foreach ($attachments as $key => &$val) {
  119 + if ($val['is_attachment'] == 1) {
  120 + if (isset($this->file_name_prefix)) {
  121 + $name = $destination . '/' . $this->file_name_prefix . mb_decode_mimeheader($val['name']);
  122 + } else {
  123 + $name = $destination . '/' . mb_decode_mimeheader($val['name']);
  124 + }
  125 + $ext = pathinfo($name, PATHINFO_EXTENSION);
  126 + mb_internal_encoding("UTF-8");
  127 + file_put_contents($name, $val['attachment']);
  128 + $this->setSavedFile( $name , $ext );
  129 + $result = true;
  130 + }
  131 +
  132 + }
  133 + }
  134 +
  135 + }
  136 +
  137 + }
  138 +
  139 + }
  140 +
  141 + return $result;
  142 + }
  143 +
  144 + /**
  145 + * @return array
  146 + */
  147 + public function getSavedFilesArr()
  148 + {
  149 + return $this->saved_files_arr;
  150 + }
  151 +
  152 + /**
  153 + * @param array $saved_files_arr
  154 + */
  155 + public function setSavedFile($saved_file, $saved_file_ext)
  156 + {
  157 + $this->saved_files_arr[$saved_file] = $saved_file_ext;
  158 + }
  159 +
  160 +
  161 +}
0 \ No newline at end of file 162 \ No newline at end of file
common/components/mail/MailReader.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: Tsurkanov
  5 + * Date: 02.11.2015
  6 + * Time: 16:47
  7 + */
  8 +
  9 +namespace common\components\mail;
  10 +
  11 +
  12 +abstract class MailReader {
  13 +
  14 + public $connection;
  15 + protected $hostname;
  16 + protected $username;
  17 + protected $password;
  18 +
  19 + /* get information specific to this email */
  20 +// $overview = imap_fetch_overview($inbox, $email_number, 0);
  21 +// $message = imap_fetchbody($inbox, $email_number, 2);
  22 +
  23 + function __construct( $hostname, $username, $password )
  24 + {
  25 + $this->hostname = $hostname;
  26 + $this->username = $username;
  27 + $this->password = $password;
  28 + }
  29 +
  30 + /**
  31 + * @return mixed
  32 + */
  33 + public function getHostname()
  34 + {
  35 + return $this->hostname;
  36 + }
  37 +
  38 + public abstract function getListMailboxes();
  39 +
  40 + public abstract function getEmails( $flag );
  41 +
  42 + public abstract function getEmailBody( $email_number, $section );
  43 +
  44 + public abstract function getCurrentEmailStructure( $email );
  45 +
  46 + public abstract function reOpen( $hostname );
  47 +
  48 +
  49 +
  50 +}
0 \ No newline at end of file 51 \ No newline at end of file
common/components/parsers/CustomConverter.php
@@ -10,71 +10,11 @@ use backend\models\ImportersPrefix; @@ -10,71 +10,11 @@ use backend\models\ImportersPrefix;
10 class CustomConverter extends Converter 10 class CustomConverter extends Converter
11 { 11 {
12 12
13 - /**  
14 - * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи  
15 - * @param $key_array - ключи для вложенного массива  
16 - * @return array - таблица с проименованными колонками  
17 - */  
18 public static $sign; 13 public static $sign;
19 public static $multiplier; 14 public static $multiplier;
20 public static $importer_id; 15 public static $importer_id;
21 public static $brand; 16 public static $brand;
22 17
23 - public static function convertToAssocArray(array $value_arr, array $key_array, $key_prefix = '')  
24 - {  
25 - // очистка служебного префикса в массиве заголовков  
26 - if ($key_prefix) {  
27 - // @todo оптимизировать - два переворота массива - избыточно  
28 - $key_array = array_flip($key_array);  
29 -  
30 - array_walk($key_array, function (&$value, $key, $key_prefix) {  
31 - $value = str_replace($key_prefix, '', $value);  
32 - }, $key_prefix);  
33 -  
34 - $key_array = array_flip($key_array);  
35 - //уберем пустые элементы  
36 - $key_array = array_filter($key_array, function ($value) {  
37 - return $value !== '';  
38 - });  
39 - }  
40 -  
41 - array_walk($value_arr,  
42 - function (&$value, $key, $key_array) {  
43 - $res = $value;  
44 - foreach ($res as $sub_key => $sub_value) {  
45 - if (isset($key_array[$sub_key])) {  
46 - // если такой ключ в базовом массиве (массиве ключей) есть, то заменим новым, иначе просто удалим  
47 - $new_key = $key_array[$sub_key];  
48 - if (!array_key_exists($new_key, $res)) {  
49 - $res[$new_key] = $value[$sub_key];  
50 - }  
51 - }  
52 - unset($res[$sub_key]);  
53 - $value = $res;  
54 - }  
55 -  
56 - },  
57 - $key_array);  
58 -  
59 - return $value_arr;  
60 - }  
61 -  
62 - /**  
63 - * @param $value_arr - двумерный массив к которому нужно добавить колонки  
64 - * @param $add_array - массив с колонками (ключи) и значениями колонок  
65 - * @return mixed  
66 - */  
67 - public function addColumns(array $value_arr, array $add_array)  
68 - {  
69 - $i = 0;  
70 - while ($i < count($value_arr)) {  
71 - foreach ($add_array as $add_key => $add_value) {  
72 - $value_arr[$i][$add_key] = $add_value;  
73 - }  
74 - $i++;  
75 - }  
76 - return $value_arr;  
77 - }  
78 18
79 public static function convertToDetails(array $row) 19 public static function convertToDetails(array $row)
80 { 20 {
@@ -143,11 +83,8 @@ class CustomConverter extends Converter @@ -143,11 +83,8 @@ class CustomConverter extends Converter
143 83
144 } 84 }
145 85
146 - public static function convertToArticle( $value, $importer_id = '' ) 86 + public static function convertToArticle( $value )
147 { 87 {
148 - if(isset( $importer_id )){  
149 - self::$importer_id = $importer_id;  
150 - }  
151 88
152 if (is_array($value)) { 89 if (is_array($value)) {
153 90
@@ -189,7 +126,7 @@ class CustomConverter extends Converter @@ -189,7 +126,7 @@ class CustomConverter extends Converter
189 126
190 public static function convertToBrand($value) 127 public static function convertToBrand($value)
191 { 128 {
192 - $res = parent::convertToEncode($value);; 129 + $res = self::convertToEncode($value);;
193 $res = trim(strtoupper($res)); 130 $res = trim(strtoupper($res));
194 $res = str_replace("Ä", "A", str_replace("Ö", "O", str_replace("Ü", "U", str_replace("Ë", "E", str_replace("Ò", "O", $res))))); 131 $res = str_replace("Ä", "A", str_replace("Ö", "O", str_replace("Ü", "U", str_replace("Ë", "E", str_replace("Ò", "O", $res)))));
195 $res = str_replace(array('@', '#', '~', '"', "'", "?", "!"), '', $res); 132 $res = str_replace(array('@', '#', '~', '"', "'", "?", "!"), '', $res);
@@ -197,12 +134,5 @@ class CustomConverter extends Converter @@ -197,12 +134,5 @@ class CustomConverter extends Converter
197 return $res; 134 return $res;
198 } 135 }
199 136
200 - public static function convertToString($value)  
201 - {  
202 - $value = parent::convertToEncode($value);  
203 -  
204 - return str_replace(array('!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '~', '`', '"', "'", ' ', '№', '%', ';', ':', '[', ']', '{', '}', '*', '?', '/', '\'', '|', '.', ',', '<', '>', '\\'), '', $value);  
205 - }  
206 -  
207 137
208 } 138 }
209 \ No newline at end of file 139 \ No newline at end of file
common/components/parsers/CustomCsvParser.php
@@ -19,31 +19,19 @@ class CustomCsvParser extends \yii\multiparser\CsvParser { @@ -19,31 +19,19 @@ class CustomCsvParser extends \yii\multiparser\CsvParser {
19 public $last_line = 100; 19 public $last_line = 100;
20 //public $hasHeaderRow = true; 20 //public $hasHeaderRow = true;
21 // public $keys = ['first','second', 'third', 'forth', 'fifth']; 21 // public $keys = ['first','second', 'third', 'forth', 'fifth'];
22 - public function setupConverter()  
23 - {  
24 - if (!count($this->converter_conf)) {  
25 - if ($this->hasHeaderRow) {  
26 - // если у файла есть заголовок, то в результате имеем ассоциативный массив  
27 - $this->converter_conf['hasKey'] = 1;  
28 -  
29 - }  
30 -  
31 - }  
32 -// $this->converter = \Yii::createObject( $this->converter_conf );  
33 -// CustomVarDamp::dumpAndDie($this->converter);  
34 - }  
35 -  
36 - /**  
37 - * @param $arr  
38 - * @return mixed  
39 - * преобразовует значения прочитанного массива в нужные типы, согласно конфигурации конвертера  
40 - */  
41 - protected function convert($arr)  
42 - {  
43 - $arr = \Yii::$app->multiparser->convertByConfiguration( $arr, $this->converter_conf );  
44 -  
45 - return $arr;  
46 -  
47 - } 22 +// public function setupConverter()
  23 +// {
  24 +// if (!count($this->converter_conf)) {
  25 +// if ($this->hasHeaderRow) {
  26 +// // если у файла есть заголовок, то в результате имеем ассоциативный массив
  27 +// $this->converter_conf['hasKey'] = 1;
  28 +//
  29 +// }
  30 +//
  31 +// }
  32 +//// $this->converter = \Yii::createObject( $this->converter_conf );
  33 +// }
  34 +
  35 +
48 36
49 } 37 }
50 \ No newline at end of file 38 \ No newline at end of file
common/components/parsers/MailParser.php deleted
1 -<?php  
2 -/**  
3 - * Created by PhpStorm.  
4 - * User: Cibermag  
5 - * Date: 01.09.2015  
6 - * Time: 10:53  
7 - */  
8 -  
9 -namespace common\components\parsers;  
10 -  
11 -  
12 -class MailParser {  
13 - public static function requestAction(){  
14 - $hostname = '{imap.gmail.com:993/imap/ssl/novalidate-cert/norsh}Inbox';  
15 - $username = 'сюда твой логин';  
16 - $password = 'сюда твой пароль';  
17 -  
18 - /* try to connect */  
19 - $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());  
20 -  
21 -  
22 - $emails = imap_search($inbox,'FROM forallthings');  
23 -  
24 - /* if emails are returned, cycle through each... */  
25 - /* if emails are returned, cycle through each... */  
26 - if($emails) {  
27 -  
28 - /* begin output var */  
29 - $output = '';  
30 -  
31 - /* put the newest emails on top */  
32 - rsort($emails);  
33 -  
34 -  
35 - foreach ($emails as $email_number) {  
36 -  
37 - /* get information specific to this email */  
38 - $overview = imap_fetch_overview($inbox, $email_number, 0);  
39 - $message = imap_fetchbody($inbox, $email_number, 2);  
40 - $structure = imap_fetchstructure($inbox, $email_number);  
41 -  
42 -  
43 -  
44 -  
45 - $attachments = array();  
46 - if (isset($structure->parts) && count($structure->parts)) {  
47 - for ($i = 0; $i < count($structure->parts); $i++) {  
48 - $attachments[$i] = array(  
49 - 'is_attachment' => false,  
50 - 'filename' => '',  
51 - 'name' => '',  
52 - 'attachment' => '');  
53 -  
54 - if ($structure->parts[$i]->ifdparameters) {  
55 - foreach ($structure->parts[$i]->dparameters as $object) {  
56 - if (strtolower($object->attribute) == 'filename') {  
57 - $attachments[$i]['is_attachment'] = true;  
58 - $attachments[$i]['filename'] = $object->value;  
59 - }  
60 - }  
61 - }  
62 -  
63 - if ($structure->parts[$i]->ifparameters) {  
64 - foreach ($structure->parts[$i]->parameters as $object) {  
65 - if (strtolower($object->attribute) == 'name') {  
66 - $attachments[$i]['is_attachment'] = true;  
67 - $attachments[$i]['name'] = $object->value;  
68 - }  
69 - }  
70 - }  
71 -  
72 - if ($attachments[$i]['is_attachment']) {  
73 - $attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i + 1);  
74 - if ($structure->parts[$i]->encoding == 3) { // 3 = BASE64  
75 - $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);  
76 - } elseif ($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE  
77 - $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);  
78 - }  
79 - }  
80 - } // for($i = 0; $i < count($structure->parts); $i++)  
81 - } // if(isset($structure->parts) && count($structure->parts))  
82 -  
83 -  
84 - if (count($attachments) != 0) {  
85 -  
86 -  
87 - foreach ($attachments as $at) {  
88 -  
89 - if ($at['is_attachment'] == 1) {  
90 - //die(__DIR__);  
91 - file_put_contents('test.csv', $at['attachment']);  
92 -  
93 - }  
94 - }  
95 -  
96 - }  
97 -  
98 - }  
99 -  
100 - // echo $output;  
101 - }  
102 - /* close the connection */  
103 - imap_close($inbox);  
104 - }  
105 -}  
106 \ No newline at end of file 0 \ No newline at end of file
common/components/parsers/config.php
@@ -5,23 +5,23 @@ @@ -5,23 +5,23 @@
5 ['class' => 'common\components\parsers\CustomCsvParser', 5 ['class' => 'common\components\parsers\CustomCsvParser',
6 'auto_detect_first_line' => true, 6 'auto_detect_first_line' => true,
7 'converter_conf' => [ 7 'converter_conf' => [
8 - //'class' => ' common\components\parsers\CustomConverter', // @todo переделать на компонент 8 + 'class' => 'common\components\parsers\CustomConverter',
9 'configuration' => ["encode" => 'DESCR'],] 9 'configuration' => ["encode" => 'DESCR'],]
10 ], 10 ],
11 'console' => 11 'console' =>
12 ['class' => 'common\components\parsers\CustomCsvParser', 12 ['class' => 'common\components\parsers\CustomCsvParser',
13 'auto_detect_first_line' => true, 13 'auto_detect_first_line' => true,
14 - 'hasHeaderRow' => true,  
15 'converter_conf' => [ 14 'converter_conf' => [
16 - //'class' => ' common\components\parsers\CustomConverter',  
17 - 'hasKey' => 1,  
18 - 'configuration' => ["string" => 'DESCR', 15 + 'class' => ' common\components\parsers\CustomConverter',
  16 + 'configuration' => ["encode" => 'DESCR',
  17 + "string" => 'DESCR',
19 "float" => 'PRICE', 18 "float" => 'PRICE',
20 "brand" => 'BRAND', 19 "brand" => 'BRAND',
21 "integer" => ['BOX','ADD_BOX'], 20 "integer" => ['BOX','ADD_BOX'],
22 "multiply" => [], 21 "multiply" => [],
23 "article" => [], 22 "article" => [],
24 "details" => [] 23 "details" => []
  24 +
25 ] 25 ]
26 ],], 26 ],],
27 27
@@ -39,11 +39,9 @@ @@ -39,11 +39,9 @@
39 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser', 39 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser',
40 'auto_detect_first_line' => true, 40 'auto_detect_first_line' => true,
41 'min_column_quantity' => 4, 41 'min_column_quantity' => 4,
42 - 'hasHeaderRow' => true,  
43 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'], 42 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'],
44 'converter_conf' => [ 43 'converter_conf' => [
45 - //'class' => ' common\components\parsers\CustomConverter',  
46 - 'hasKey' => 1, 44 + 'class' => ' common\components\parsers\CustomConverter',
47 'configuration' => [ 45 'configuration' => [
48 "brand" => ['BRAND', 'CROSS_BRAND'], 46 "brand" => ['BRAND', 'CROSS_BRAND'],
49 "crosses" => [], 47 "crosses" => [],
@@ -54,21 +52,33 @@ @@ -54,21 +52,33 @@
54 ['console' => 52 ['console' =>
55 ['class' => 'yii\multiparser\XmlParser', 53 ['class' => 'yii\multiparser\XmlParser',
56 'node' => 'Товар', 54 'node' => 'Товар',
  55 + 'has_header_row' => true,
  56 + 'keys' => [
  57 + "BRAND" => 'Производитель',
  58 + "ARTICLE"=> 'Код',
  59 + "PRICE" => 'Розница',
  60 + "DESCR" => 'Наименование',
  61 + "BOX" => 'Колво',
  62 + "ADD_BOX"=> 'Ожидаемое',
  63 + "GROUP" => 'Группа'
  64 + ],
57 'converter_conf' => [ 65 'converter_conf' => [
58 - //'class' => ' common\components\parsers\CustomConverter',  
59 - 'hasKey' => 1, 66 + 'class' => 'common\components\parsers\CustomConverter',
60 'configuration' => ["details" => [] 67 'configuration' => ["details" => []
61 ],], 68 ],],
62 ], 69 ],
63 - 'basic_column' => [  
64 - "BRAND" => 'Производитель',  
65 - "ARTICLE"=> 'Код',  
66 - "PRICE" => 'Розница',  
67 - "DESCR" => 'Наименование',  
68 - "BOX" => 'Колво',  
69 - "ADD_BOX"=> 'Ожидаемое',  
70 - "GROUP" => 'Группа'  
71 - ],  
72 ], 70 ],
  71 + 'xlsx' =>
  72 + ['web' =>
  73 + ['class' => 'yii\multiparser\XlsxParser',
  74 + 'path_for_extract_files' => \Yii::getAlias('@temp_upload') . '/xlsx/',
  75 + // 'has_header_row' => true,
  76 + 'active_sheet' => 1,
  77 + 'converter_conf' => [
  78 + 'class' => 'common\components\parsers\CustomConverter',
  79 + 'configuration' => ["string" => []],
  80 + ]
  81 + ],
  82 + ]
73 ]; 83 ];
74 84
common/config/main.php
@@ -15,14 +15,15 @@ return [ @@ -15,14 +15,15 @@ return [
15 ] 15 ]
16 ], 16 ],
17 'multiparser'=>[ 17 'multiparser'=>[
18 -  
19 'class' => 'yii\multiparser\YiiMultiparser', 18 'class' => 'yii\multiparser\YiiMultiparser',
20 'configuration' => $mp_configuration, 19 'configuration' => $mp_configuration,
21 - 'as behavior' => [  
22 - 'class' => 'common\components\parsers\CustomConverter', 20 + ],
  21 + 'converter'=>[
  22 + 'class' => 'yii\multiparser\YiiConverter',
  23 + 'configuration' => [
  24 + 'class' => 'common\components\parsers\CustomConverter'
  25 + ],
23 ], 26 ],
24 27
25 ], 28 ],
26 - ],  
27 -  
28 ]; 29 ];
common/models/Cart.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "{{%cart}}".
  9 + *
  10 + * @property string $bill_id
  11 + * @property string $account_id
  12 + * @property string $count
  13 + * @property double $price
  14 + * @property double $price_purchase
  15 + * @property integer $status
  16 + * @property string $article
  17 + * @property string $brand
  18 + * @property string $descr
  19 + * @property string $import_id
  20 + * @property string $timestamp
  21 + */
  22 +class Cart extends \backend\components\base\BaseActiveRecord
  23 +{
  24 + /**
  25 + * @inheritdoc
  26 + */
  27 + public static function tableName()
  28 + {
  29 + return '{{%cart}}';
  30 + }
  31 +
  32 + /**
  33 + * @inheritdoc
  34 + */
  35 + public function rules()
  36 + {
  37 + return [
  38 + [['bill_id', 'account_id', 'count', 'price', 'price_purchase', 'article', 'brand', 'descr', 'import_id'], 'required'],
  39 + [['bill_id', 'account_id', 'count', 'status', 'import_id'], 'integer'],
  40 + [['price', 'price_purchase'], 'number'],
  41 + [['timestamp'], 'safe'],
  42 + [['article', 'brand'], 'string', 'max' => 100],
  43 + [['descr'], 'string', 'max' => 254]
  44 + ];
  45 + }
  46 +
  47 + /**
  48 + * @inheritdoc
  49 + */
  50 + public function attributeLabels()
  51 + {
  52 + return [
  53 + 'bill_id' => Yii::t('app', 'Bill ID'),
  54 + 'account_id' => Yii::t('app', 'Account ID'),
  55 + 'count' => Yii::t('app', 'Count'),
  56 + 'price' => Yii::t('app', 'Price'),
  57 + 'price_purchase' => Yii::t('app', 'Price Purchase'),
  58 + 'status' => Yii::t('app', 'Status'),
  59 + 'article' => Yii::t('app', 'Article'),
  60 + 'brand' => Yii::t('app', 'Brand'),
  61 + 'descr' => Yii::t('app', 'Descr'),
  62 + 'import_id' => Yii::t('app', 'Import ID'),
  63 + 'timestamp' => Yii::t('app', 'Timestamp'),
  64 + ];
  65 + }
  66 +}
common/models/CartBills.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "{{%cart_bills}}".
  9 + *
  10 + * @property string $id
  11 + * @property string $account_id
  12 + * @property string $manager_id
  13 + * @property string $office_id
  14 + * @property string $status
  15 + * @property string $f1
  16 + * @property string $f2
  17 + * @property string $f3
  18 + * @property string $message
  19 + * @property integer $safe_bill
  20 + * @property string $delivery
  21 + * @property double $delivery_price
  22 + * @property string $timestamp
  23 + */
  24 +class CartBills extends \backend\components\base\BaseActiveRecord
  25 +{
  26 + /**
  27 + * @inheritdoc
  28 + */
  29 + public static function tableName()
  30 + {
  31 + return '{{%cart_bills}}';
  32 + }
  33 +
  34 + /**
  35 + * @inheritdoc
  36 + */
  37 + public function rules()
  38 + {
  39 + return [
  40 + [['account_id', 'office_id', 'f1', 'f2', 'f3', 'message', 'delivery'], 'required'],
  41 + [['account_id', 'manager_id', 'office_id', 'status', 'safe_bill'], 'integer'],
  42 + [['message'], 'string'],
  43 + [['delivery_price'], 'number'],
  44 + [['timestamp'], 'safe'],
  45 + [['f1', 'f3'], 'string', 'max' => 150],
  46 + [['f2'], 'string', 'max' => 50],
  47 + [['delivery'], 'string', 'max' => 100]
  48 + ];
  49 + }
  50 +
  51 + /**
  52 + * @inheritdoc
  53 + */
  54 + public function attributeLabels()
  55 + {
  56 + return [
  57 + 'id' => Yii::t('app', 'ID'),
  58 + 'account_id' => Yii::t('app', 'Account ID'),
  59 + 'manager_id' => Yii::t('app', 'Manager ID'),
  60 + 'office_id' => Yii::t('app', 'Office ID'),
  61 + 'status' => Yii::t('app', 'Status'),
  62 + 'f1' => Yii::t('app', 'F1'),
  63 + 'f2' => Yii::t('app', 'F2'),
  64 + 'f3' => Yii::t('app', 'F3'),
  65 + 'message' => Yii::t('app', 'Message'),
  66 + 'safe_bill' => Yii::t('app', 'Safe Bill'),
  67 + 'delivery' => Yii::t('app', 'Delivery'),
  68 + 'delivery_price' => Yii::t('app', 'Delivery Price'),
  69 + 'timestamp' => Yii::t('app', 'Timestamp'),
  70 + ];
  71 + }
  72 +}
common/models/CartBillsSearch.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use common\components\CustomVarDamp;
  6 +use Yii;
  7 +use yii\base\Model;
  8 +use yii\data\ActiveDataProvider;
  9 +use common\models\CartBillsView;
  10 +
  11 +/**
  12 + * CartBillsSearch represents the model behind the search form about `common\models\CartBills`.
  13 + */
  14 +class CartBillsSearch extends CartBillsView
  15 +{
  16 + public $date_to;
  17 + /**
  18 + * @inheritdoc
  19 + */
  20 + public function rules()
  21 + {
  22 + return [
  23 + [['id', 'account_id', 'status'], 'integer'],
  24 + [['dt', 'date_to'], 'string', 'max' => 10],
  25 + ];
  26 + }
  27 +
  28 + /**
  29 + * @inheritdoc
  30 + */
  31 + public function scenarios()
  32 + {
  33 + // bypass scenarios() implementation in the parent class
  34 + return Model::scenarios();
  35 + }
  36 +
  37 + /**
  38 + * Creates data provider instance with search query applied
  39 + *
  40 + * @param array $params
  41 + *
  42 + * @return ActiveDataProvider
  43 + */
  44 + public function search($params)
  45 + {
  46 + $query = CartBillsView::find();
  47 +
  48 + $dataProvider = new ActiveDataProvider([
  49 + 'query' => $query,
  50 + ]);
  51 +
  52 + $this->load($params);
  53 +
  54 + if (!$this->validate()) {
  55 + // uncomment the following line if you do not want to return any records when validation fails
  56 + // $query->where('0=1');
  57 + return $dataProvider;
  58 + }
  59 +
  60 + $query->andFilterWhere([
  61 + 'id' => $this->id,
  62 + 'account_id' => $this->account_id,
  63 + 'status_id' => $this->status,
  64 + ]);
  65 +
  66 + if($this->dt !== null || $this->date_to !== null){
  67 + $date_from = mktime(0,0,0,(int)substr($this->dt,4,2),(int)substr($this->dt,1,2),(int)substr($this->dt,7,4));
  68 + $date_to = mktime(23,59,59,(int)substr($this->date_to,4,2),(int)substr($this->date_to,1,2),(int)substr($this->date_to,7,4));
  69 +
  70 + $query->andFilterWhere([
  71 + 'between', 'dt', $date_from, $date_to
  72 + ]);
  73 + }
  74 +
  75 +
  76 +
  77 +// $query->andFilterWhere(['like', 'f1', $this->f1])
  78 +// ->andFilterWhere(['like', 'f2', $this->f2])
  79 +// ->andFilterWhere(['like', 'f3', $this->f3])
  80 +// ->andFilterWhere(['like', 'message', $this->message])
  81 +// ->andFilterWhere(['like', 'delivery', $this->delivery]);
  82 +
  83 + return $dataProvider;
  84 + }
  85 +
  86 + public static function findById($id){
  87 +
  88 + return CartBillsView::find()->where(['id' => $id])->one();
  89 + }
  90 +}
common/models/CartBillsView.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "w_cart_bills_view".
  9 + *
  10 + * @property string $id
  11 + * @property string $account_id
  12 + * @property string $manager_name
  13 + * @property string $dt
  14 + * @property string $name
  15 + * @property string $phone
  16 + * @property string $email
  17 + * @property string $delivery
  18 + * @property string $status_id
  19 + * @property string $status
  20 + * @property string $message
  21 + * @property integer $safe_bill
  22 + * @property string $sum
  23 + * @property string $scode
  24 + */
  25 +class CartBillsView extends \backend\components\base\BaseActiveRecord
  26 +{
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public static function tableName()
  31 + {
  32 + return 'w_cart_bills_view';
  33 + }
  34 +
  35 + /**
  36 + * @inheritdoc
  37 + */
  38 + public function rules()
  39 + {
  40 + return [
  41 + [['id', 'account_id', 'dt', 'status_id', 'safe_bill', 'scode'], 'integer'],
  42 + [['account_id', 'name', 'phone', 'email', 'delivery', 'status', 'message'], 'required'],
  43 + [['message'], 'string'],
  44 + [['sum'], 'number'],
  45 + [['manager_name'], 'string', 'max' => 255],
  46 + [['name', 'email'], 'string', 'max' => 150],
  47 + [['phone', 'status'], 'string', 'max' => 50],
  48 + [['delivery'], 'string', 'max' => 100]
  49 + ];
  50 + }
  51 +
  52 + /**
  53 + * @inheritdoc
  54 + */
  55 + public function attributeLabels()
  56 + {
  57 + return [
  58 + 'id' => Yii::t('app', '№ заказа'),
  59 + 'account_id' => Yii::t('app', '№ клиента'),
  60 + 'manager_name' => Yii::t('app', 'Менеджер'),
  61 + 'dt' => Yii::t('app', 'Дата'),
  62 + 'name' => Yii::t('app', 'Name'),
  63 + 'phone' => Yii::t('app', 'Phone'),
  64 + 'email' => Yii::t('app', 'Email'),
  65 + 'delivery' => Yii::t('app', 'Delivery'),
  66 + 'status_id' => Yii::t('app', 'Status ID'),
  67 + 'status' => Yii::t('app', 'Статус'),
  68 + 'message' => Yii::t('app', 'Message'),
  69 + 'safe_bill' => Yii::t('app', 'Safe Bill'),
  70 + 'sum' => Yii::t('app', 'Сумма'),
  71 + 'scode' => Yii::t('app', 'Scode'),
  72 + ];
  73 + }
  74 +
  75 + public static function findById($id){
  76 +
  77 + }
  78 +}
common/models/CartView.php 0 → 100644
  1 +<?php
  2 +
  3 +namespace common\models;
  4 +
  5 +use Yii;
  6 +
  7 +/**
  8 + * This is the model class for table "{{%cart_view}}".
  9 + *
  10 + * @property string $id
  11 + * @property string $account_id
  12 + * @property string $dt
  13 + * @property string $user_name
  14 + * @property string $user_mail
  15 + * @property integer $status_id
  16 + * @property string $status
  17 + * @property string $article
  18 + * @property string $brand
  19 + * @property string $descr
  20 + * @property string $importer
  21 + * @property string $count
  22 + * @property double $price
  23 + * @property string $import_id
  24 + */
  25 +class CartView extends \backend\components\base\BaseActiveRecord
  26 +{
  27 + /**
  28 + * @inheritdoc
  29 + */
  30 + public static function tableName()
  31 + {
  32 + return '{{%cart_view}}';
  33 + }
  34 +
  35 + /**
  36 + * @inheritdoc
  37 + */
  38 + public function rules()
  39 + {
  40 + return [
  41 + [['id', 'account_id', 'dt', 'status_id', 'count', 'import_id'], 'integer'],
  42 + [['account_id', 'user_name', 'user_mail', 'status', 'article', 'brand', 'descr', 'importer', 'count', 'price', 'import_id'], 'required'],
  43 + [['price'], 'number'],
  44 + [['user_name', 'user_mail'], 'string', 'max' => 150],
  45 + [['status'], 'string', 'max' => 50],
  46 + [['article', 'brand'], 'string', 'max' => 100],
  47 + [['descr', 'importer'], 'string', 'max' => 254]
  48 + ];
  49 + }
  50 +
  51 + /**
  52 + * @inheritdoc
  53 + */
  54 + public function attributeLabels()
  55 + {
  56 + return [
  57 + 'id' => Yii::t('app', 'ID'),
  58 + 'account_id' => Yii::t('app', 'Account ID'),
  59 + 'dt' => Yii::t('app', 'Dt'),
  60 + 'user_name' => Yii::t('app', 'User Name'),
  61 + 'user_mail' => Yii::t('app', 'User Mail'),
  62 + 'status_id' => Yii::t('app', 'Status ID'),
  63 + 'status' => Yii::t('app', 'Status'),
  64 + 'article' => Yii::t('app', 'Article'),
  65 + 'brand' => Yii::t('app', 'Brand'),
  66 + 'descr' => Yii::t('app', 'Descr'),
  67 + 'importer' => Yii::t('app', 'Importer'),
  68 + 'count' => Yii::t('app', 'Count'),
  69 + 'price' => Yii::t('app', 'Price'),
  70 + 'import_id' => Yii::t('app', 'Import ID'),
  71 + ];
  72 + }
  73 +}
common/models/DetailsCurrency.php
@@ -6,7 +6,7 @@ use Yii; @@ -6,7 +6,7 @@ use Yii;
6 6
7 /** 7 /**
8 * This is the model class for table "{{%details_currency}}". 8 * This is the model class for table "{{%details_currency}}".
9 - * 9 + * w_details_currency - СПЕЦИАЛЬНО СОЗАДННАЯ ВЬЮШКА ДЛЯ ДОСТУПА К СПИСКУ ТОВАРОВ С ВАЛЮТАМИ И ИХ КУРСАМИ
10 * @property string $ID 10 * @property string $ID
11 * @property string $IMPORT_ID 11 * @property string $IMPORT_ID
12 * @property string $BRAND 12 * @property string $BRAND
common/models/Margins.php
@@ -45,4 +45,22 @@ class Margins extends \yii\db\ActiveRecord @@ -45,4 +45,22 @@ class Margins extends \yii\db\ActiveRecord
45 'koef' => 'Коэффициент', 45 'koef' => 'Коэффициент',
46 ]; 46 ];
47 } 47 }
  48 +
  49 + // возвращает массив для выбора в динамических формах (конструкторах)
  50 + public static function getHeader()
  51 + {
  52 + $header_array = self::find()->asArray()->all();
  53 +
  54 + $id_arr = array_column($header_array,'id');
  55 + $name_arr = array_column($header_array,'name');
  56 + $header_array = array_combine( $id_arr, $name_arr );
  57 + $header_array['_null'] = null; // первая колонка пустая
  58 + $header_array['group'] = 'Группа RG';
  59 + ksort($header_array);
  60 +
  61 + return $header_array;
  62 + }
  63 +
  64 +
  65 +
48 } 66 }
common/models/MarginsGroups.php
@@ -74,4 +74,42 @@ class MarginsGroups extends \yii\db\ActiveRecord @@ -74,4 +74,42 @@ class MarginsGroups extends \yii\db\ActiveRecord
74 { 74 {
75 return $this->hasOne(Margins::className(), ['id' => 'margin_id']); 75 return $this->hasOne(Margins::className(), ['id' => 'margin_id']);
76 } 76 }
  77 +
  78 + /**
  79 + * вставка данных с апдейтом прямым запросом SQL
  80 + * @param $data - массив вставляемых данный, вставка будет прозводится пакетами размером указанным в константе BATCH
  81 + * @throws \yii\db\Exception
  82 + */
  83 + //@todo - вынести все ручные инсерты в отдельный класс
  84 + public static function ManualInsertWithUpdate($data, $keys)
  85 + {
  86 + // \common\components\CustomVarDamp::dumpAndDie($data);
  87 + $table_name = self::tableName();
  88 + $keys_arr = array_keys($data[0]);
  89 + // найдем те поля которые не являются ключами. Их нужно будет при дубляже апдейтить
  90 + $fields_arr_to_update = array_diff( $keys_arr, $keys );
  91 +
  92 + $query_update = ' on duplicate key update ';
  93 + foreach ($fields_arr_to_update as $field) {
  94 + $query_update .= "[[{$field}]] = values([[{$field}]]),";
  95 + }
  96 + // удалим последнюю запятую
  97 + $query_update = substr($query_update, 0, strlen($query_update) - 1);
  98 +
  99 + // запросы будем выполнять пакетами
  100 + // размер пакета установлен в константе
  101 + // разобъем массив на пакеты и будем их проходить
  102 + $data = array_chunk($data, 20);
  103 + foreach ($data as $current_batch_array) {
  104 +
  105 + //воспользуемся пакетной вставкой от фреймворка
  106 + $query_insert = Yii::$app->db->createCommand()->batchInsert($table_name, $keys_arr, $current_batch_array)->sql;
  107 +
  108 + // добавим фрагмент с апдейтом при дубляже
  109 + $query = "{$query_insert} {$query_update}";
  110 + // \common\components\CustomVarDamp::dumpAndDie($query);
  111 + Yii::$app->db->createCommand($query)->execute();
  112 +
  113 + }
  114 + }
77 } 115 }
@@ -18,7 +18,11 @@ @@ -18,7 +18,11 @@
18 "yiisoft/yii2": ">=2.0.6", 18 "yiisoft/yii2": ">=2.0.6",
19 "yiisoft/yii2-bootstrap": "*", 19 "yiisoft/yii2-bootstrap": "*",
20 "yiisoft/yii2-swiftmailer": "*", 20 "yiisoft/yii2-swiftmailer": "*",
21 - "yiisoft/yii2-imagine": "*" 21 + "artweb/yii2-multiparser": "dev-master",
  22 + "yiisoft/yii2-imagine": "*",
  23 + "kartik-v/yii2-widget-datepicker": "^1.3",
  24 + "kartik-v/yii2-field-range": "^1.3",
  25 + "kartik-v/yii2-datecontrol": "dev-master"
22 }, 26 },
23 "require-dev": { 27 "require-dev": {
24 "yiisoft/yii2-codeception": "*", 28 "yiisoft/yii2-codeception": "*",
@@ -4,9 +4,55 @@ @@ -4,9 +4,55 @@
4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 "This file is @generated automatically" 5 "This file is @generated automatically"
6 ], 6 ],
7 - "hash": "8580bd82955b1fbb80d47024e184056e", 7 + "hash": "2d5c03f681f1c72d09f36e10af144465",
  8 + "content-hash": "4c8b69eb2733ca32596e438952d2f182",
8 "packages": [ 9 "packages": [
9 { 10 {
  11 + "name": "artweb/yii2-multiparser",
  12 + "version": "dev-master",
  13 + "source": {
  14 + "type": "git",
  15 + "url": "https://github.com/tsurkanovm/yii-multiparser.git",
  16 + "reference": "0c6fd004d8739f106a58f584661e1e5327958b34"
  17 + },
  18 + "dist": {
  19 + "type": "zip",
  20 + "url": "https://api.github.com/repos/tsurkanovm/yii-multiparser/zipball/0c6fd004d8739f106a58f584661e1e5327958b34",
  21 + "reference": "0c6fd004d8739f106a58f584661e1e5327958b34",
  22 + "shasum": ""
  23 + },
  24 + "require": {
  25 + "yiisoft/yii2": "*"
  26 + },
  27 + "type": "library",
  28 + "autoload": {
  29 + "psr-4": {
  30 + "yii\\multiparser\\": "lib\\"
  31 + }
  32 + },
  33 + "notification-url": "https://packagist.org/downloads/",
  34 + "license": [
  35 + "MIT"
  36 + ],
  37 + "authors": [
  38 + {
  39 + "name": "Mihail Tsurkanov",
  40 + "email": "tsurkanovm@gmail.com",
  41 + "role": "Developer"
  42 + }
  43 + ],
  44 + "description": "This extension provides a Multiparser solution for Yii framework 2.0.",
  45 + "homepage": "https://github.com/tsurkanovm/yii-multiparser.git",
  46 + "keywords": [
  47 + "csv",
  48 + "parser",
  49 + "xlsx",
  50 + "xml",
  51 + "yii2"
  52 + ],
  53 + "time": "2015-10-28 09:28:22"
  54 + },
  55 + {
10 "name": "bower-asset/bootstrap", 56 "name": "bower-asset/bootstrap",
11 "version": "v3.3.5", 57 "version": "v3.3.5",
12 "source": { 58 "source": {
@@ -317,6 +363,296 @@ @@ -317,6 +363,296 @@
317 "time": "2013-11-30 08:25:19" 363 "time": "2013-11-30 08:25:19"
318 }, 364 },
319 { 365 {
  366 + "name": "imagine/imagine",
  367 + "version": "v0.5.0",
  368 + "source": {
  369 + "type": "git",
  370 + "url": "https://github.com/avalanche123/Imagine.git",
  371 + "reference": "f64ec666baaa800edcbf237db41121a569230709"
  372 + },
  373 + "dist": {
  374 + "type": "zip",
  375 + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/f64ec666baaa800edcbf237db41121a569230709",
  376 + "reference": "f64ec666baaa800edcbf237db41121a569230709",
  377 + "shasum": ""
  378 + },
  379 + "require": {
  380 + "php": ">=5.3.2"
  381 + },
  382 + "require-dev": {
  383 + "sami/sami": "dev-master"
  384 + },
  385 + "suggest": {
  386 + "ext-gd": "to use the GD implementation",
  387 + "ext-gmagick": "to use the Gmagick implementation",
  388 + "ext-imagick": "to use the Imagick implementation"
  389 + },
  390 + "type": "library",
  391 + "autoload": {
  392 + "psr-0": {
  393 + "Imagine": "lib/"
  394 + }
  395 + },
  396 + "notification-url": "https://packagist.org/downloads/",
  397 + "license": [
  398 + "MIT"
  399 + ],
  400 + "authors": [
  401 + {
  402 + "name": "Bulat Shakirzyanov",
  403 + "email": "mallluhuct@gmail.com",
  404 + "homepage": "http://avalanche123.com"
  405 + }
  406 + ],
  407 + "description": "Image processing for PHP 5.3",
  408 + "homepage": "http://imagine.readthedocs.org/",
  409 + "keywords": [
  410 + "drawing",
  411 + "graphics",
  412 + "image manipulation",
  413 + "image processing"
  414 + ],
  415 + "time": "2013-07-10 17:25:36"
  416 + },
  417 + {
  418 + "name": "kartik-v/php-date-formatter",
  419 + "version": "v1.3.1",
  420 + "source": {
  421 + "type": "git",
  422 + "url": "https://github.com/kartik-v/php-date-formatter.git",
  423 + "reference": "7d3dc3495dd10bd1909c0dfdecd673967019cc21"
  424 + },
  425 + "dist": {
  426 + "type": "zip",
  427 + "url": "https://api.github.com/repos/kartik-v/php-date-formatter/zipball/7d3dc3495dd10bd1909c0dfdecd673967019cc21",
  428 + "reference": "7d3dc3495dd10bd1909c0dfdecd673967019cc21",
  429 + "shasum": ""
  430 + },
  431 + "type": "library",
  432 + "autoload": {
  433 + "psr-4": {
  434 + "kartik\\plugins\\dateformatter\\": ""
  435 + }
  436 + },
  437 + "notification-url": "https://packagist.org/downloads/",
  438 + "license": [
  439 + "BSD-3-Clause"
  440 + ],
  441 + "authors": [
  442 + {
  443 + "name": "Kartik Visweswaran",
  444 + "email": "kartikv2@gmail.com",
  445 + "homepage": "http://www.krajee.com/"
  446 + }
  447 + ],
  448 + "description": "A JQuery datetime formatting and manipulation library using PHP date-time formats in javascript.",
  449 + "homepage": "https://github.com/kartik-v/php-date-formatter",
  450 + "keywords": [
  451 + "date",
  452 + "datetime",
  453 + "formatter",
  454 + "javascript",
  455 + "jquery",
  456 + "php",
  457 + "php-date-formatter.js",
  458 + "time"
  459 + ],
  460 + "time": "2015-06-18 15:14:51"
  461 + },
  462 + {
  463 + "name": "kartik-v/yii2-datecontrol",
  464 + "version": "dev-master",
  465 + "source": {
  466 + "type": "git",
  467 + "url": "https://github.com/kartik-v/yii2-datecontrol.git",
  468 + "reference": "4e858b5cd38130c37739b2f582b66a044f77c95c"
  469 + },
  470 + "dist": {
  471 + "type": "zip",
  472 + "url": "https://api.github.com/repos/kartik-v/yii2-datecontrol/zipball/4e858b5cd38130c37739b2f582b66a044f77c95c",
  473 + "reference": "4e858b5cd38130c37739b2f582b66a044f77c95c",
  474 + "shasum": ""
  475 + },
  476 + "require": {
  477 + "kartik-v/php-date-formatter": ">1.3",
  478 + "kartik-v/yii2-krajee-base": "~1.7"
  479 + },
  480 + "type": "yii2-extension",
  481 + "autoload": {
  482 + "psr-4": {
  483 + "kartik\\datecontrol\\": ""
  484 + }
  485 + },
  486 + "notification-url": "https://packagist.org/downloads/",
  487 + "license": [
  488 + "BSD-3-Clause"
  489 + ],
  490 + "authors": [
  491 + {
  492 + "name": "Kartik Visweswaran",
  493 + "email": "kartikv2@gmail.com",
  494 + "homepage": "http://www.krajee.com/"
  495 + }
  496 + ],
  497 + "description": "Date control module allowing separation of formats for View and Model for Yii Framework 2.0",
  498 + "homepage": "https://github.com/kartik-v/yii2-datecontrol",
  499 + "keywords": [
  500 + "control",
  501 + "date",
  502 + "extension",
  503 + "format",
  504 + "yii",
  505 + "yii2"
  506 + ],
  507 + "time": "2015-07-30 18:30:18"
  508 + },
  509 + {
  510 + "name": "kartik-v/yii2-field-range",
  511 + "version": "v1.3.0",
  512 + "source": {
  513 + "type": "git",
  514 + "url": "https://github.com/kartik-v/yii2-field-range.git",
  515 + "reference": "095d260eecb86ff2e78a70775011cec00a75df98"
  516 + },
  517 + "dist": {
  518 + "type": "zip",
  519 + "url": "https://api.github.com/repos/kartik-v/yii2-field-range/zipball/095d260eecb86ff2e78a70775011cec00a75df98",
  520 + "reference": "095d260eecb86ff2e78a70775011cec00a75df98",
  521 + "shasum": ""
  522 + },
  523 + "require": {
  524 + "kartik-v/yii2-krajee-base": "*"
  525 + },
  526 + "type": "yii2-extension",
  527 + "autoload": {
  528 + "psr-4": {
  529 + "kartik\\field\\": ""
  530 + }
  531 + },
  532 + "notification-url": "https://packagist.org/downloads/",
  533 + "license": [
  534 + "BSD 3-Clause"
  535 + ],
  536 + "authors": [
  537 + {
  538 + "name": "Kartik Visweswaran",
  539 + "email": "kartikv2@gmail.com",
  540 + "homepage": "http://www.krajee.com/"
  541 + }
  542 + ],
  543 + "description": "Easily manage Yii 2 ActiveField ranges (from/to) with Bootstrap 3 addons markup and more",
  544 + "homepage": "https://github.com/kartik-v/yii2-field-range",
  545 + "keywords": [
  546 + "addon",
  547 + "bootstrap",
  548 + "bootstrap 3",
  549 + "date",
  550 + "extension",
  551 + "field-range",
  552 + "from",
  553 + "range",
  554 + "to",
  555 + "widget",
  556 + "yii2"
  557 + ],
  558 + "time": "2014-11-25 08:52:00"
  559 + },
  560 + {
  561 + "name": "kartik-v/yii2-krajee-base",
  562 + "version": "v1.7.7",
  563 + "source": {
  564 + "type": "git",
  565 + "url": "https://github.com/kartik-v/yii2-krajee-base.git",
  566 + "reference": "c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19"
  567 + },
  568 + "dist": {
  569 + "type": "zip",
  570 + "url": "https://api.github.com/repos/kartik-v/yii2-krajee-base/zipball/c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19",
  571 + "reference": "c0adff9d9762f4fd3bf0e7cd0000fcab0bf00f19",
  572 + "shasum": ""
  573 + },
  574 + "require": {
  575 + "yiisoft/yii2-bootstrap": "@dev"
  576 + },
  577 + "type": "yii2-extension",
  578 + "autoload": {
  579 + "psr-4": {
  580 + "kartik\\base\\": ""
  581 + }
  582 + },
  583 + "notification-url": "https://packagist.org/downloads/",
  584 + "license": [
  585 + "BSD-3-Clause"
  586 + ],
  587 + "authors": [
  588 + {
  589 + "name": "Kartik Visweswaran",
  590 + "email": "kartikv2@gmail.com",
  591 + "homepage": "http://www.krajee.com/"
  592 + }
  593 + ],
  594 + "description": "Base library and foundation components for all Yii2 Krajee extensions.",
  595 + "homepage": "https://github.com/kartik-v/yii2-krajee-base",
  596 + "keywords": [
  597 + "base",
  598 + "extension",
  599 + "foundation",
  600 + "krajee",
  601 + "widget",
  602 + "yii2"
  603 + ],
  604 + "time": "2015-06-16 05:19:57"
  605 + },
  606 + {
  607 + "name": "kartik-v/yii2-widget-datepicker",
  608 + "version": "v1.3.3",
  609 + "source": {
  610 + "type": "git",
  611 + "url": "https://github.com/kartik-v/yii2-widget-datepicker.git",
  612 + "reference": "368b181ef658c05707fe41dd16eee4d9ffd9da38"
  613 + },
  614 + "dist": {
  615 + "type": "zip",
  616 + "url": "https://api.github.com/repos/kartik-v/yii2-widget-datepicker/zipball/368b181ef658c05707fe41dd16eee4d9ffd9da38",
  617 + "reference": "368b181ef658c05707fe41dd16eee4d9ffd9da38",
  618 + "shasum": ""
  619 + },
  620 + "require": {
  621 + "kartik-v/yii2-krajee-base": "~1.7"
  622 + },
  623 + "type": "yii2-extension",
  624 + "autoload": {
  625 + "psr-4": {
  626 + "kartik\\date\\": ""
  627 + }
  628 + },
  629 + "notification-url": "https://packagist.org/downloads/",
  630 + "license": [
  631 + "BSD-3-Clause"
  632 + ],
  633 + "authors": [
  634 + {
  635 + "name": "Kartik Visweswaran",
  636 + "email": "kartikv2@gmail.com",
  637 + "homepage": "http://www.krajee.com/"
  638 + }
  639 + ],
  640 + "description": "Enhanced Yii2 wrapper for the bootstrap datepicker plugin (sub repo split from yii2-widgets).",
  641 + "homepage": "https://github.com/kartik-v/yii2-widget-datepicker",
  642 + "keywords": [
  643 + "date",
  644 + "extension",
  645 + "form",
  646 + "jquery",
  647 + "picker",
  648 + "plugin",
  649 + "select2",
  650 + "widget",
  651 + "yii2"
  652 + ],
  653 + "time": "2015-07-19 04:49:03"
  654 + },
  655 + {
320 "name": "swiftmailer/swiftmailer", 656 "name": "swiftmailer/swiftmailer",
321 "version": "v5.4.1", 657 "version": "v5.4.1",
322 "source": { 658 "source": {
@@ -459,21 +795,21 @@ @@ -459,21 +795,21 @@
459 }, 795 },
460 { 796 {
461 "name": "yiisoft/yii2-bootstrap", 797 "name": "yiisoft/yii2-bootstrap",
462 - "version": "2.0.4", 798 + "version": "2.0.5",
463 "source": { 799 "source": {
464 "type": "git", 800 "type": "git",
465 "url": "https://github.com/yiisoft/yii2-bootstrap.git", 801 "url": "https://github.com/yiisoft/yii2-bootstrap.git",
466 - "reference": "1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0" 802 + "reference": "1464f93834b1d5edb1f5625f7ffd6c3723fa4923"
467 }, 803 },
468 "dist": { 804 "dist": {
469 "type": "zip", 805 "type": "zip",
470 - "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0",  
471 - "reference": "1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0", 806 + "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/1464f93834b1d5edb1f5625f7ffd6c3723fa4923",
  807 + "reference": "1464f93834b1d5edb1f5625f7ffd6c3723fa4923",
472 "shasum": "" 808 "shasum": ""
473 }, 809 },
474 "require": { 810 "require": {
475 "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*", 811 "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*",
476 - "yiisoft/yii2": ">=2.0.4" 812 + "yiisoft/yii2": ">=2.0.6"
477 }, 813 },
478 "type": "yii2-extension", 814 "type": "yii2-extension",
479 "extra": { 815 "extra": {
@@ -505,7 +841,7 @@ @@ -505,7 +841,7 @@
505 "bootstrap", 841 "bootstrap",
506 "yii2" 842 "yii2"
507 ], 843 ],
508 - "time": "2015-05-10 22:08:17" 844 + "time": "2015-09-23 17:48:24"
509 }, 845 },
510 { 846 {
511 "name": "yiisoft/yii2-composer", 847 "name": "yiisoft/yii2-composer",
@@ -555,6 +891,54 @@ @@ -555,6 +891,54 @@
555 "time": "2015-03-01 06:22:44" 891 "time": "2015-03-01 06:22:44"
556 }, 892 },
557 { 893 {
  894 + "name": "yiisoft/yii2-imagine",
  895 + "version": "2.0.3",
  896 + "source": {
  897 + "type": "git",
  898 + "url": "https://github.com/yiisoft/yii2-imagine.git",
  899 + "reference": "0961343138b65bba447de84b2b300899617e6acc"
  900 + },
  901 + "dist": {
  902 + "type": "zip",
  903 + "url": "https://api.github.com/repos/yiisoft/yii2-imagine/zipball/0961343138b65bba447de84b2b300899617e6acc",
  904 + "reference": "0961343138b65bba447de84b2b300899617e6acc",
  905 + "shasum": ""
  906 + },
  907 + "require": {
  908 + "imagine/imagine": "0.5.*",
  909 + "yiisoft/yii2": "*"
  910 + },
  911 + "type": "yii2-extension",
  912 + "extra": {
  913 + "branch-alias": {
  914 + "dev-master": "2.0.x-dev"
  915 + }
  916 + },
  917 + "autoload": {
  918 + "psr-4": {
  919 + "yii\\imagine\\": ""
  920 + }
  921 + },
  922 + "notification-url": "https://packagist.org/downloads/",
  923 + "license": [
  924 + "BSD-3-Clause"
  925 + ],
  926 + "authors": [
  927 + {
  928 + "name": "Antonio Ramirez",
  929 + "email": "amigo.cobos@gmail.com"
  930 + }
  931 + ],
  932 + "description": "The Imagine integration for the Yii framework",
  933 + "keywords": [
  934 + "helper",
  935 + "image",
  936 + "imagine",
  937 + "yii2"
  938 + ],
  939 + "time": "2015-03-01 06:22:44"
  940 + },
  941 + {
558 "name": "yiisoft/yii2-swiftmailer", 942 "name": "yiisoft/yii2-swiftmailer",
559 "version": "2.0.4", 943 "version": "2.0.4",
560 "source": { 944 "source": {
@@ -634,101 +1018,6 @@ @@ -634,101 +1018,6 @@
634 } 1018 }
635 }, 1019 },
636 { 1020 {
637 - "name": "composer/installers",  
638 - "version": "v1.0.21",  
639 - "source": {  
640 - "type": "git",  
641 - "url": "https://github.com/composer/installers.git",  
642 - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45"  
643 - },  
644 - "dist": {  
645 - "type": "zip",  
646 - "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",  
647 - "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",  
648 - "shasum": ""  
649 - },  
650 - "replace": {  
651 - "roundcube/plugin-installer": "*",  
652 - "shama/baton": "*"  
653 - },  
654 - "require-dev": {  
655 - "composer/composer": "1.0.*@dev",  
656 - "phpunit/phpunit": "4.1.*"  
657 - },  
658 - "type": "composer-installer",  
659 - "extra": {  
660 - "class": "Composer\\Installers\\Installer",  
661 - "branch-alias": {  
662 - "dev-master": "1.0-dev"  
663 - }  
664 - },  
665 - "autoload": {  
666 - "psr-0": {  
667 - "Composer\\Installers\\": "src/"  
668 - }  
669 - },  
670 - "notification-url": "https://packagist.org/downloads/",  
671 - "license": [  
672 - "MIT"  
673 - ],  
674 - "authors": [  
675 - {  
676 - "name": "Kyle Robinson Young",  
677 - "email": "kyle@dontkry.com",  
678 - "homepage": "https://github.com/shama"  
679 - }  
680 - ],  
681 - "description": "A multi-framework Composer library installer",  
682 - "homepage": "http://composer.github.com/installers/",  
683 - "keywords": [  
684 - "Craft",  
685 - "Dolibarr",  
686 - "Hurad",  
687 - "MODX Evo",  
688 - "OXID",  
689 - "SMF",  
690 - "Thelia",  
691 - "WolfCMS",  
692 - "agl",  
693 - "aimeos",  
694 - "annotatecms",  
695 - "bitrix",  
696 - "cakephp",  
697 - "chef",  
698 - "codeigniter",  
699 - "concrete5",  
700 - "croogo",  
701 - "dokuwiki",  
702 - "drupal",  
703 - "elgg",  
704 - "fuelphp",  
705 - "grav",  
706 - "installer",  
707 - "joomla",  
708 - "kohana",  
709 - "laravel",  
710 - "lithium",  
711 - "magento",  
712 - "mako",  
713 - "mediawiki",  
714 - "modulework",  
715 - "moodle",  
716 - "phpbb",  
717 - "piwik",  
718 - "ppi",  
719 - "puppet",  
720 - "roundcube",  
721 - "shopware",  
722 - "silverstripe",  
723 - "symfony",  
724 - "typo3",  
725 - "wordpress",  
726 - "zend",  
727 - "zikula"  
728 - ],  
729 - "time": "2015-02-18 17:17:01"  
730 - },  
731 - {  
732 "name": "fzaninotto/faker", 1021 "name": "fzaninotto/faker",
733 "version": "v1.5.0", 1022 "version": "v1.5.0",
734 "source": { 1023 "source": {
@@ -815,55 +1104,6 @@ @@ -815,55 +1104,6 @@
815 "time": "2013-11-01 13:02:21" 1104 "time": "2013-11-01 13:02:21"
816 }, 1105 },
817 { 1106 {
818 - "name": "silverstripe/framework",  
819 - "version": "3.1.13",  
820 - "source": {  
821 - "type": "git",  
822 - "url": "https://github.com/silverstripe/silverstripe-framework.git",  
823 - "reference": "04b803dfc6dc60f2e6a38fa74f957156230b54be"  
824 - },  
825 - "dist": {  
826 - "type": "zip",  
827 - "url": "https://api.github.com/repos/silverstripe/silverstripe-framework/zipball/04b803dfc6dc60f2e6a38fa74f957156230b54be",  
828 - "reference": "04b803dfc6dc60f2e6a38fa74f957156230b54be",  
829 - "shasum": ""  
830 - },  
831 - "require": {  
832 - "composer/installers": "*",  
833 - "php": ">=5.3.2"  
834 - },  
835 - "require-dev": {  
836 - "phpunit/phpunit": "~3.7@stable"  
837 - },  
838 - "type": "silverstripe-module",  
839 - "autoload": {  
840 - "classmap": [  
841 - "tests/behat/features/bootstrap"  
842 - ]  
843 - },  
844 - "notification-url": "https://packagist.org/downloads/",  
845 - "license": [  
846 - "BSD-3-Clause"  
847 - ],  
848 - "authors": [  
849 - {  
850 - "name": "SilverStripe",  
851 - "homepage": "http://silverstripe.com"  
852 - },  
853 - {  
854 - "name": "The SilverStripe Community",  
855 - "homepage": "http://silverstripe.org"  
856 - }  
857 - ],  
858 - "description": "The SilverStripe framework",  
859 - "homepage": "http://silverstripe.org",  
860 - "keywords": [  
861 - "framework",  
862 - "silverstripe"  
863 - ],  
864 - "time": "2015-05-28 06:59:11"  
865 - },  
866 - {  
867 "name": "yiisoft/yii2-codeception", 1107 "name": "yiisoft/yii2-codeception",
868 "version": "2.0.4", 1108 "version": "2.0.4",
869 "source": { 1109 "source": {
@@ -1058,7 +1298,10 @@ @@ -1058,7 +1298,10 @@
1058 ], 1298 ],
1059 "aliases": [], 1299 "aliases": [],
1060 "minimum-stability": "stable", 1300 "minimum-stability": "stable",
1061 - "stability-flags": [], 1301 + "stability-flags": {
  1302 + "artweb/yii2-multiparser": 20,
  1303 + "kartik-v/yii2-datecontrol": 20
  1304 + },
1062 "prefer-stable": false, 1305 "prefer-stable": false,
1063 "prefer-lowest": false, 1306 "prefer-lowest": false,
1064 "platform": { 1307 "platform": {
console/.gitignore
1 -/old_migrations  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +/old_migrations
  3 +/runtime
3 \ No newline at end of file 4 \ No newline at end of file
console/controllers/ParserController.php
1 <?php 1 <?php
2 namespace console\controllers; 2 namespace console\controllers;
3 3
  4 +use common\components\archive_reader\ArchiveCreator;
4 use common\components\CustomVarDamp; 5 use common\components\CustomVarDamp;
  6 +use common\components\mail\ImapMailReader;
  7 +use common\components\mail\MailAttachmentsSaver;
5 use yii\console\Controller; 8 use yii\console\Controller;
6 use yii\helpers\Console; 9 use yii\helpers\Console;
7 use common\components\PriceWriter; 10 use common\components\PriceWriter;
@@ -59,8 +62,7 @@ class ParserController extends Controller @@ -59,8 +62,7 @@ class ParserController extends Controller
59 } 62 }
60 $data = \Yii::$app->multiparser->parse( $file_path, $parser_config ); 63 $data = \Yii::$app->multiparser->parse( $file_path, $parser_config );
61 if ( ! $data ) { 64 if ( ! $data ) {
62 - // @todo переделать, что бы ошибка автоматически останавливала сценарий  
63 - return false; 65 + throw new ErrorException("Ошибка обработки файла прайса!");
64 } 66 }
65 67
66 $writer = new PriceWriter(); 68 $writer = new PriceWriter();
@@ -105,7 +107,7 @@ class ParserController extends Controller @@ -105,7 +107,7 @@ class ParserController extends Controller
105 ]; 107 ];
106 108
107 if ($this->parseFileConsole($file_path, $config)) { 109 if ($this->parseFileConsole($file_path, $config)) {
108 - unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.xml'); 110 + //unlink(\Yii::getAlias('@auto_upload') . '/' . $file_name . '.xml');
109 \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser'); 111 \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
110 } else { 112 } else {
111 \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser'); 113 \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
@@ -115,8 +117,52 @@ class ParserController extends Controller @@ -115,8 +117,52 @@ class ParserController extends Controller
115 117
116 public function actionTest() 118 public function actionTest()
117 { 119 {
118 - Console::output('It is working '); 120 + Console::output('It is working');
119 \Yii::info('2', 'parser'); 121 \Yii::info('2', 'parser');
120 122
121 } 123 }
  124 +
  125 + public function actionSaveMailAttachments()
  126 + {
  127 + \Yii::info('Начало сохранения файлов почты', 'mail');
  128 +
  129 + $mail_reader = new ImapMailReader( '{imap.gmail.com:993/imap/ssl/novalidate-cert}', 'tsurkanovm@gmail.com', 'Wtvr@2000' );
  130 + $mailboxes = $mail_reader->getListMailboxes();
  131 + foreach ( $mailboxes as $custom_label ) {
  132 + $words = explode(" ",str_replace( array($mail_reader->getHostname(),"!"),"",imap_utf7_decode($custom_label)) );
  133 + $importer_id = (int)preg_replace("/[^A-Z0-9]+/","", strtoupper($words[0]));
  134 +
  135 + $mail_reader->reOpen( $custom_label );
  136 + $saver = new MailAttachmentsSaver( $mail_reader, 'UNSEEN' );
  137 + $saver->file_name_parefix = $importer_id . '~!~';
  138 + $saver->saveAttachmentsTo(\Yii::getAlias('@temp_upload'));
  139 +
  140 + }
  141 +
  142 + $files = $saver->getSavedFilesArr();
  143 + $arch_creator = new ArchiveCreator();
  144 + $arch_extensions = $arch_creator->getHandleExtension();
  145 + $files_on_unpack = array_intersect( $files , $arch_extensions );
  146 + foreach ($files_on_unpack as $arch_ext => $arch_name) {
  147 + $arch_reader = $arch_creator->create( $arch_name, $arch_ext);
  148 + $arch_reader->extractTo(\Yii::getAlias('@temp_upload'));
  149 + unset( $files[$arch_name] );
  150 + $files = array_merge( $files, $arch_reader->getExtractedFiles());
  151 + }
  152 +
  153 + foreach ( $files as $name => $ext ) {
  154 + $file_name = '';
  155 + if( $ext = 'csv' ){
  156 + $files_model = new ImportersFiles();
  157 + $files_model->importer_id = $importer_id;
  158 + if ($files_model->save()) {
  159 + $file_name = \Yii::$app->db->getLastInsertID();
  160 + } // обработчик ошибки !!!!!
  161 +
  162 + }
  163 +
  164 + // переписываем файл в автолоад папку, и переименовываем если указано имя
  165 + }
  166 +
  167 + }
122 } 168 }
123 \ No newline at end of file 169 \ No newline at end of file
console/migrations/m151013_062829_deletePrefixFunction.php
@@ -57,4 +57,4 @@ MySQL; @@ -57,4 +57,4 @@ MySQL;
57 } 57 }
58 58
59 59
60 -} 60 -}
  61 +}
61 \ No newline at end of file 62 \ No newline at end of file
console/migrations/m151016_144435_addViewDetailsCurrency.php
1 <?php 1 <?php
2 2
3 -use yii\db\Schema;  
4 use yii\db\Migration; 3 use yii\db\Migration;
5 4
6 class m151016_144435_addViewDetailsCurrency extends Migration 5 class m151016_144435_addViewDetailsCurrency extends Migration
console/migrations/m151030_121905_addSumBillFunction.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +/**
  6 + * Class m151030_121905_addSumBillFunction
  7 + * добавляем функцию расчета суммы заказа
  8 + */
  9 +class m151030_121905_addSumBillFunction extends Migration
  10 +{
  11 +
  12 + public function safeUp()
  13 + {
  14 + $sum_count = <<< MySQL
  15 + CREATE FUNCTION SumBill(p_bill_id int) RETURNS DECIMAL(12,2)
  16 + BEGIN
  17 + DECLARE _sum DECIMAL(12,2);
  18 +
  19 + select round(sum(`count`*`price`),2) into _sum From w_cart where bill_id = p_bill_id;
  20 +
  21 + RETURN (_sum);
  22 + END
  23 +MySQL;
  24 +
  25 + $this->execute($sum_count);
  26 +
  27 + }
  28 +
  29 + public function safedown()
  30 + {
  31 +
  32 + $sum_count = <<< MySQL
  33 + drop FUNCTION SumBill;
  34 +MySQL;
  35 +
  36 + $this->execute($sum_count);
  37 +
  38 + }
  39 +
  40 +
  41 +}
0 \ No newline at end of file 42 \ No newline at end of file
console/migrations/m151030_123511_addCartBillsView.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +
  6 +class m151030_123511_addCartBillsView extends Migration
  7 +{
  8 + public function up()
  9 + {
  10 +
  11 + $view = <<< MySQL
  12 + create view w_cart_bills_view as
  13 + select `w_cart_bills`.`id` as `id`,
  14 + `w_cart_bills`.`account_id`,
  15 + `w__user`.`name` as `manager_name`,
  16 + unix_timestamp(`w_cart_bills`.`timestamp`) as `dt`,
  17 + `w_cart_bills`.`f1` as `name`,
  18 + `w_cart_bills`.`f2` as `phone`,
  19 + `w_cart_bills`.`f3` as `email`,
  20 + `w_cart_bills`.`delivery`,
  21 + `w_cart_bills`.`status` as `status_id`,
  22 + `w_dic_statuses`.`name` as `status`,
  23 + `w_cart_bills`.`message`,`w_cart_bills`.`safe_bill`,
  24 + SumBill(`w_cart_bills`.`id`) as `sum`,
  25 + `w_accounts`.`scode`
  26 + from `w_cart_bills`
  27 + left join `w_accounts` on `w_accounts`.`id` = `w_cart_bills`.`account_id`
  28 + left join `w__user` on `w__user`.`id` = `w_cart_bills`.`manager_id`
  29 + inner join `w_dic_statuses` on `w_dic_statuses`.`id` = `w_cart_bills`.`status`;
  30 +MySQL;
  31 +
  32 + $this->execute($view);
  33 +
  34 + }
  35 +
  36 + public function down()
  37 + {
  38 + // вернем все как было
  39 + $drop_view = 'drop view if exists w_cart_bills_view';
  40 +
  41 + $this->execute($drop_view);
  42 +
  43 + }
  44 +}
  45 +
  46 +
  47 +
console/migrations/m151030_133110_addCartView.php 0 → 100644
  1 +<?php
  2 +
  3 +use yii\db\Migration;
  4 +
  5 +class m151030_133110_addCartView extends Migration
  6 +{
  7 + public function up()
  8 + {
  9 +
  10 + $view = <<< MySQL
  11 + create view w_cart_view as
  12 + select `w_cart_bills`.`id`,
  13 + `w_cart_bills`.`account_id`,
  14 + unix_timestamp(`w_cart_bills`.`timestamp`) as `dt`,
  15 + `w_cart_bills`.`f1` as `user_name`,
  16 + `w_cart_bills`.`f3` as `user_mail`,
  17 + `w_cart`.`status` as `status_id`,
  18 + `w_dic_statuses`.`name` as `status`,
  19 + `w_cart`.`article`,`w_cart`.`brand`,`w_cart`.`descr`,
  20 + `w_importers`.`name` as `importer`,
  21 + `w_cart`.`count`,`w_cart`.`price`,
  22 + `w_cart`.`import_id`
  23 + from `w_cart`
  24 + inner join `w_importers` on `w_importers`.`id` = `w_cart`.`import_id`
  25 + inner join `w_cart_bills` on `w_cart_bills`.`id` = `w_cart`.`bill_id`
  26 + inner join `w_dic_statuses` on `w_dic_statuses`.`id` = `w_cart`.`status`;
  27 +MySQL;
  28 +
  29 + $this->execute($view);
  30 +
  31 + }
  32 +
  33 + public function down()
  34 + {
  35 + // вернем все как было
  36 + $drop_view = 'drop view if exists w_cart_view';
  37 +
  38 + $this->execute($drop_view);
  39 +
  40 + }
  41 +}
console/runtime/.gitignore
1 -* 1 +/logs
2 !.gitignore 2 !.gitignore
3 \ No newline at end of file 3 \ No newline at end of file
frontend/web/.htaccess 0 → 100644
  1 +RewriteEngine on
  2 +RewriteBase /
  3 +RewriteCond %{REQUEST_FILENAME} !-f
  4 +RewriteCond %{REQUEST_FILENAME} !-d
  5 +
  6 +RewriteRule . index.php
  7 +
  8 +Options -Indexes
0 \ No newline at end of file 9 \ No newline at end of file