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
.gitignore
1 1 .idea
2   -/uploads
3 2 \ No newline at end of file
  3 +/uploads
  4 +/vendor
4 5 \ No newline at end of file
... ...
backend/components/base/BaseActiveRecord.php
... ... @@ -9,4 +9,17 @@
9 9 namespace backend\components\base;
10 10  
11 11  
12   -class BaseActiveRecord extends \yii\db\ActiveRecord {}
13 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 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 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 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 1 <?php
2 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 8 use Yii;
5 9 use yii\data\ActiveDataProvider;
6 10 use yii\filters\AccessControl;
... ... @@ -15,6 +19,7 @@ use backend\models\Importers;
15 19 use yii\base\ErrorException;
16 20 use common\components\PriceWriter;
17 21 use common\components\CustomVarDamp;
  22 +use common\components\CustomArrayHelper;
18 23  
19 24 /**
20 25 * Parser controller
... ... @@ -51,10 +56,10 @@ class ParserController extends BaseController
51 56  
52 57 public function actionIndex($mode = 0)
53 58 {
  59 + $this->mailTest();
54 60 $model = new UploadFileParsingForm();
55 61 // установим режим, 0 - ручная загрузка, 1 - автозагрузка
56 62 $model->mode = $mode;
57   - //CustomVarDamp::dumpAndDie(phpinfo());
58 63 return $this->render('index', ['model' => $model]);
59 64 }
60 65  
... ... @@ -81,7 +86,6 @@ class ParserController extends BaseController
81 86 try {
82 87 $files_model->save();
83 88 } catch (ErrorException $e) {
84   - // CustomVarDamp::dump($e->getMessage());
85 89 throw $e;
86 90 }
87 91 // получим id только что записанной записи - его запишем в название файла
... ... @@ -125,11 +129,12 @@ class ParserController extends BaseController
125 129  
126 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 140 } else if (Yii::$app->getCache()->get('parser_data')) {
... ... @@ -145,7 +150,6 @@ class ParserController extends BaseController
145 150 ],
146 151 ]);
147 152  
148   -
149 153 $last_index = end( array_flip( $data[0] ) );
150 154 $header_counts = $last_index + 1;
151 155 //формируем заголовок для пользователя, где он сможет выбрать соответсвие полей (выпадающий список)
... ... @@ -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 196 $writer = new PriceWriter();
... ... @@ -287,5 +291,71 @@ class ParserController extends BaseController
287 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 36 /**
37 37 * @var bool - признак необходимости удалить префикс Артикула перед вставкой
38 38 */
  39 +
39 40 public $delete_price = false;
40 41  
41 42 /**
... ... @@ -131,6 +132,9 @@ class Details extends BaseActiveRecord
131 132  
132 133 //воспользуемся пакетной вставкой от фреймворка
133 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 139 $query = "{$query_insert} {$query_update}";
136 140 // \common\components\CustomVarDamp::dumpAndDie($query);
... ... @@ -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 48 return [
49 49 ['importer_id', 'required', 'message' => 'Не указан поставщик!' ],
50 50 ['file', 'required', 'message' => 'Не выбран файл!' ],
51   - [['file'], 'file', 'extensions' => ['csv', 'xml'], 'checkExtensionByMimeType'=>false ],
  51 + [['file'], 'file', 'extensions' => ['csv', 'xlsx'], 'checkExtensionByMimeType'=>false ],
52 52 ['importer_id', 'integer','max' => 999999, 'min' => 0 ],
53 53 [['action','delete_prefix', 'delete_price', 'success'], 'boolean', 'except' => 'auto' ], // только для ручной загрузки
54 54 ['delimiter', 'string', 'max' => 1],
... ... @@ -71,12 +71,15 @@ class UploadFileParsingForm extends Model
71 71 public function readFile( $options = [] ){
72 72  
73 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 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 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 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 282 echo Menu::widget([
283 283 'options' => ['class' => 'sidebar-menu'],
284 284 'items' => [
  285 + ['label' => 'Заказы', 'url' => ['cart/index']],
285 286 ['label' => "Загрузка файлов", 'url' => ['#'], 'items' => [
  287 + ['label' => 'Кросс файлы', 'url' => ['crossing-upload/index']],
  288 + ['label' => 'Группы RG', 'url' => ['rg-grup/index']],
286 289 ['label' => 'Файлы на сервере', 'url' => ['parser/server-files']],
287 290 ['label' => 'Загрузить файл на сервер', 'url' => ['parser/index', 'mode' => 1]],
288 291 ['label' => 'Ручная загрузка', 'url' => ['parser/index']],
... ... @@ -317,10 +320,7 @@ $this-&gt;beginContent(&#39;@app/views/layouts/main.php&#39;);
317 320 ['label' => 'Vin коды', 'url' => ['currency/index']],
318 321 ['label' => 'Запросы по номеру', 'url' => ['currency/index']],
319 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 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 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 77 \ No newline at end of file
... ...
common/components/PriceWriter.php
... ... @@ -62,20 +62,20 @@ class PriceWriter
62 62 // преобразуем числовые значения
63 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 69 $row['FULL_ARTICLE'] = $row['ARTICLE'];
70 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 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 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 81 $details_model->load(['Details' => $row]);
... ... @@ -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 91 try {
92 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 95 $details_model->delete_price = true;
96 96 }
97 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 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 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 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 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 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 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 51 \ No newline at end of file
... ...
common/components/parsers/CustomConverter.php
... ... @@ -10,71 +10,11 @@ use backend\models\ImportersPrefix;
10 10 class CustomConverter extends Converter
11 11 {
12 12  
13   - /**
14   - * @param $value_arr - двумерный массив значений, которому нужно присвоить ключи
15   - * @param $key_array - ключи для вложенного массива
16   - * @return array - таблица с проименованными колонками
17   - */
18 13 public static $sign;
19 14 public static $multiplier;
20 15 public static $importer_id;
21 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 19 public static function convertToDetails(array $row)
80 20 {
... ... @@ -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 89 if (is_array($value)) {
153 90  
... ... @@ -189,7 +126,7 @@ class CustomConverter extends Converter
189 126  
190 127 public static function convertToBrand($value)
191 128 {
192   - $res = parent::convertToEncode($value);;
  129 + $res = self::convertToEncode($value);;
193 130 $res = trim(strtoupper($res));
194 131 $res = str_replace("Ä", "A", str_replace("Ö", "O", str_replace("Ü", "U", str_replace("Ë", "E", str_replace("Ò", "O", $res)))));
195 132 $res = str_replace(array('@', '#', '~', '"', "'", "?", "!"), '', $res);
... ... @@ -197,12 +134,5 @@ class CustomConverter extends Converter
197 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 139 \ No newline at end of file
... ...
common/components/parsers/CustomCsvParser.php
... ... @@ -19,31 +19,19 @@ class CustomCsvParser extends \yii\multiparser\CsvParser {
19 19 public $last_line = 100;
20 20 //public $hasHeaderRow = true;
21 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 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 0 \ No newline at end of file
common/components/parsers/config.php
... ... @@ -5,23 +5,23 @@
5 5 ['class' => 'common\components\parsers\CustomCsvParser',
6 6 'auto_detect_first_line' => true,
7 7 'converter_conf' => [
8   - //'class' => ' common\components\parsers\CustomConverter', // @todo переделать на компонент
  8 + 'class' => 'common\components\parsers\CustomConverter',
9 9 'configuration' => ["encode" => 'DESCR'],]
10 10 ],
11 11 'console' =>
12 12 ['class' => 'common\components\parsers\CustomCsvParser',
13 13 'auto_detect_first_line' => true,
14   - 'hasHeaderRow' => true,
15 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 18 "float" => 'PRICE',
20 19 "brand" => 'BRAND',
21 20 "integer" => ['BOX','ADD_BOX'],
22 21 "multiply" => [],
23 22 "article" => [],
24 23 "details" => []
  24 +
25 25 ]
26 26 ],],
27 27  
... ... @@ -39,11 +39,9 @@
39 39 'crosses' => ['class' => 'common\components\parsers\CustomCsvParser',
40 40 'auto_detect_first_line' => true,
41 41 'min_column_quantity' => 4,
42   - 'hasHeaderRow' => true,
43 42 'keys' =>['ARTICLE', 'CROSS_ARTICLE', 'BRAND', 'CROSS_BRAND'],
44 43 'converter_conf' => [
45   - //'class' => ' common\components\parsers\CustomConverter',
46   - 'hasKey' => 1,
  44 + 'class' => ' common\components\parsers\CustomConverter',
47 45 'configuration' => [
48 46 "brand" => ['BRAND', 'CROSS_BRAND'],
49 47 "crosses" => [],
... ... @@ -54,21 +52,33 @@
54 52 ['console' =>
55 53 ['class' => 'yii\multiparser\XmlParser',
56 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 65 'converter_conf' => [
58   - //'class' => ' common\components\parsers\CustomConverter',
59   - 'hasKey' => 1,
  66 + 'class' => 'common\components\parsers\CustomConverter',
60 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 15 ]
16 16 ],
17 17 'multiparser'=>[
18   -
19 18 'class' => 'yii\multiparser\YiiMultiparser',
20 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 6  
7 7 /**
8 8 * This is the model class for table "{{%details_currency}}".
9   - *
  9 + * w_details_currency - СПЕЦИАЛЬНО СОЗАДННАЯ ВЬЮШКА ДЛЯ ДОСТУПА К СПИСКУ ТОВАРОВ С ВАЛЮТАМИ И ИХ КУРСАМИ
10 10 * @property string $ID
11 11 * @property string $IMPORT_ID
12 12 * @property string $BRAND
... ...
common/models/Margins.php
... ... @@ -45,4 +45,22 @@ class Margins extends \yii\db\ActiveRecord
45 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 74 {
75 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 }
... ...
composer.json
... ... @@ -18,7 +18,11 @@
18 18 "yiisoft/yii2": ">=2.0.6",
19 19 "yiisoft/yii2-bootstrap": "*",
20 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 27 "require-dev": {
24 28 "yiisoft/yii2-codeception": "*",
... ...
composer.lock
... ... @@ -4,9 +4,55 @@
4 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 5 "This file is @generated automatically"
6 6 ],
7   - "hash": "8580bd82955b1fbb80d47024e184056e",
  7 + "hash": "2d5c03f681f1c72d09f36e10af144465",
  8 + "content-hash": "4c8b69eb2733ca32596e438952d2f182",
8 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 56 "name": "bower-asset/bootstrap",
11 57 "version": "v3.3.5",
12 58 "source": {
... ... @@ -317,6 +363,296 @@
317 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 656 "name": "swiftmailer/swiftmailer",
321 657 "version": "v5.4.1",
322 658 "source": {
... ... @@ -459,21 +795,21 @@
459 795 },
460 796 {
461 797 "name": "yiisoft/yii2-bootstrap",
462   - "version": "2.0.4",
  798 + "version": "2.0.5",
463 799 "source": {
464 800 "type": "git",
465 801 "url": "https://github.com/yiisoft/yii2-bootstrap.git",
466   - "reference": "1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0"
  802 + "reference": "1464f93834b1d5edb1f5625f7ffd6c3723fa4923"
467 803 },
468 804 "dist": {
469 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 808 "shasum": ""
473 809 },
474 810 "require": {
475 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 814 "type": "yii2-extension",
479 815 "extra": {
... ... @@ -505,7 +841,7 @@
505 841 "bootstrap",
506 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 847 "name": "yiisoft/yii2-composer",
... ... @@ -555,6 +891,54 @@
555 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 942 "name": "yiisoft/yii2-swiftmailer",
559 943 "version": "2.0.4",
560 944 "source": {
... ... @@ -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 1021 "name": "fzaninotto/faker",
733 1022 "version": "v1.5.0",
734 1023 "source": {
... ... @@ -815,55 +1104,6 @@
815 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 1107 "name": "yiisoft/yii2-codeception",
868 1108 "version": "2.0.4",
869 1109 "source": {
... ... @@ -1058,7 +1298,10 @@
1058 1298 ],
1059 1299 "aliases": [],
1060 1300 "minimum-stability": "stable",
1061   - "stability-flags": [],
  1301 + "stability-flags": {
  1302 + "artweb/yii2-multiparser": 20,
  1303 + "kartik-v/yii2-datecontrol": 20
  1304 + },
1062 1305 "prefer-stable": false,
1063 1306 "prefer-lowest": false,
1064 1307 "platform": {
... ...
console/.gitignore
1   -/old_migrations
2 1 \ No newline at end of file
  2 +/old_migrations
  3 +/runtime
3 4 \ No newline at end of file
... ...
console/controllers/ParserController.php
1 1 <?php
2 2 namespace console\controllers;
3 3  
  4 +use common\components\archive_reader\ArchiveCreator;
4 5 use common\components\CustomVarDamp;
  6 +use common\components\mail\ImapMailReader;
  7 +use common\components\mail\MailAttachmentsSaver;
5 8 use yii\console\Controller;
6 9 use yii\helpers\Console;
7 10 use common\components\PriceWriter;
... ... @@ -59,8 +62,7 @@ class ParserController extends Controller
59 62 }
60 63 $data = \Yii::$app->multiparser->parse( $file_path, $parser_config );
61 64 if ( ! $data ) {
62   - // @todo переделать, что бы ошибка автоматически останавливала сценарий
63   - return false;
  65 + throw new ErrorException("Ошибка обработки файла прайса!");
64 66 }
65 67  
66 68 $writer = new PriceWriter();
... ... @@ -105,7 +107,7 @@ class ParserController extends Controller
105 107 ];
106 108  
107 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 111 \Yii::info("Загрузка файла - $file_path успешно завершена", 'parser');
110 112 } else {
111 113 \Yii::error("Загрузка файла - $file_path завершена с ошибкой", 'parser');
... ... @@ -115,8 +117,52 @@ class ParserController extends Controller
115 117  
116 118 public function actionTest()
117 119 {
118   - Console::output('It is working ');
  120 + Console::output('It is working');
119 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 169 \ No newline at end of file
... ...
console/migrations/m151013_062829_deletePrefixFunction.php
... ... @@ -57,4 +57,4 @@ MySQL;
57 57 }
58 58  
59 59  
60 60 -}
  61 +}
61 62 \ No newline at end of file
... ...
console/migrations/m151016_144435_addViewDetailsCurrency.php
1 1 <?php
2 2  
3   -use yii\db\Schema;
4 3 use yii\db\Migration;
5 4  
6 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 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 2 !.gitignore
3 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 9 \ No newline at end of file
... ...