mode = $mode; } /** * @param mixed $configuration */ public function setConfiguration($configuration) { $this->configuration = $configuration; } /** * @param mixed $data */ public function setData($data) { $this->data = $data; } /** * @return mixed */ public function getValidatedMsg() { return $this->validated_msg; } /** * @return mixed */ public function hasValidationError() { return $this->hasValidationError; } public function writePriceToDB() { // 1. запишем дату старта в таблицу файлов поставщика (ImportersFiles) // id загруженного файла получим из конфигурации $files_model = ImportersFiles::findOne($this->configuration['record_id']); $update_date = date('Y-m-d H:i:s'); $files_model->time_start = $update_date; // запишем дату начала загрузки if (!$files_model->save()) { throw new \ErrorException(implode(', ', $files_model->getErrors())); } // 2. конвертируем данные // только для ручной загрузки, в авто режиме все делает конвертер при первом же проходе (в процессе парсинга) if ( $this->mode == 0 ) { // преобразуем значения перед записью в БД $this->convertDataByConfiguration(); } //3. провалидируем полученные данные моделью - Details $details_model = $this->validateByDetailsModel(); if ( empty($this->data) ) { // после валидации не осталось валидных данных для записи return false; } //4. дополним данные значением импортера и даты обновления цены $this->data = CustomArrayHelper::addColumns($this->data, ['IMPORT_ID' => $this->configuration['importer_id'], 'timestamp' => $update_date]); //5. запишем данные в связанные таблицы $this->writePriceInTransaction($details_model, $files_model, $update_date); return true; } public function deletePriceFromDB() { $importer_id = ''; $update_date = ''; if (isset($this->configuration['importer_id'])) $importer_id = $this->configuration['importer_id']; if (isset($this->configuration['update_date'])) $update_date = $this->configuration['update_date']; if (!$importer_id) { throw new \ErrorException('Не указан поставщик прайса для удаления'); } elseif (!$update_date) { throw new \ErrorException('Не указана дата загрузки прайса для удаления'); } $this->deletePriceInTransaction( $importer_id, $update_date ); return true; } /** * ковертирует отпарсенные данные конвертером по конфигурации */ protected function convertDataByConfiguration () { foreach ($this->data as &$row) { if (isset($row['PRICE'])) $row['PRICE'] = \Yii::$app->converter->convertTo('float', $row['PRICE']); if (isset($row['BOX'])) $row['BOX'] = \Yii::$app->converter->convertTo('integer', $row['BOX']); // присвоим полный артикул if (isset($row['ARTICLE'])) { $row['FULL_ARTICLE'] = $row['ARTICLE']; if ((int)$this->configuration['delete_prefix']) { $row = \Yii::$app->converter->convertTo('Article', $row, ['importer_id' => $this->configuration['importer_id']]); } else { if (isset($row['ARTICLE'])) $row['ARTICLE'] = \Yii::$app->converter->convertTo('Article', $row['ARTICLE']); } } if (isset($row['ADD_BOX'])) $row['ADD_BOX'] = \Yii::$app->converter->convertTo('integer', $row['ADD_BOX']); } } protected function writePriceInTransaction($details_model, $files_model, $update_date){ $transaction = \Yii::$app->db->beginTransaction(); try { if (isset($this->configuration['delete_price']) && (int)$this->configuration['delete_price']) { $details_model->delete_price = true; } //2. попытаемся вставить данные в БД с апдейтом по ключам $details_model->manualInsert($this->data, $this->configuration['importer_id']); // 3. зафиксируем дату конца загрузки в файлах поставщика if (!$files_model->save()) { $transaction->rollBack(); throw new \ErrorException(implode(', ', $files_model->getErrors())); } // 4. зафиксируем дату загрузки в таблице поставщиков $imp_model = Importers::findOne($this->configuration['importer_id']); $imp_model->price_date_update = $update_date; if (!$imp_model->save()) { $transaction->rollBack(); $imp_model->throwStringErrorException(); } $transaction->commit(); } catch (ErrorException $e) { $transaction->rollBack(); throw new \ErrorException($e->getMessage()); } } protected function deletePriceInTransaction( $importer_id, $update_date ){ $transaction = \Yii::$app->db->beginTransaction(); try { // 1. удалим из таблицы файлов поставщика (ImportersFiles) $rows = ImportersFiles::deleteAll(['importer_id' => $importer_id, 'time_start' => $update_date]); if ($rows != 1) { $transaction->rollBack(); throw new \ErrorException('Ошибка удаления из таблицы файлов поставщиков. Указанный прайс не найден'); } $last_upload_time = ImportersFiles::find()->where(['importer_id' => $importer_id])->orderBy(['time_start' => SORT_DESC])->one()->time_start; // 2. удалим прайс из таблицы товаров (Details) $details_model = new Details(); $conditions = "import_id = {$importer_id} AND timestamp ='$update_date'"; $details_model->manualDelete( $conditions ); // 3. откатимся до старой даты загрузки в таблице поставщиков $imp_model = Importers::findOne( $importer_id ); $imp_model->price_date_update = $last_upload_time; if (!$imp_model->save()) { $transaction->rollBack(); $imp_model->throwStringErrorException(); } $transaction->commit(); } catch (ErrorException $e) { $transaction->rollBack(); throw new \ErrorException($e->getMessage()); } } protected function validateByDetailsModel(){ $details_model = new Details(); $model_validator = new ModelArrayValidator( $details_model ); $this->data = $model_validator->validate( $this->data ); $this->validated_msg = $model_validator->getMassage(); $this->hasValidationError = $model_validator->hasError(); $model_validator->close(); return $details_model; } }