public void ImportCatalogFile() { _source.SourceClassName = typeof(RostaCertificateSource).Name; _source.SearchInAssortmentPrice = true; _source.DecodeTableUrl = "ftp://*****:*****@ftp.apteka-raduga.ru:21/LIST/SERT_LIST.DBF"; FileHelper.InitDir(Path.Combine(Settings.Default.FTPOptBoxPath, "LIST")); File.Copy(@"..\..\Data\RostaSertList.dbf", Path.Combine(Settings.Default.FTPOptBoxPath, "LIST", "SERT_LIST.DBF")); var rostaCertList = Dbf.Load(@"..\..\Data\RostaSertList.dbf"); var supplierCode = rostaCertList.Rows[0]["CODE"].ToString(); //Берем первый попавшийся продукт var product = session.Query <TestProduct>().First(); var price = _supplier.Prices[0]; //Прайс-лист должен быть ассортиментным price.PriceType = PriceType.Assortment; price.AddProductSynonym(product.CatalogProduct.Name + " Тестовый", product); var synonym = price.ProductSynonyms[price.ProductSynonyms.Count - 1]; session.Save(price); var core = new TestCore(synonym) { Price = price, Code = supplierCode, Quantity = "0", Period = "01.01.2015" }; session.Save(core); var catalogs = session.Query <CertificateSourceCatalog>().Where(c => c.CertificateSource == _source).ToList(); Assert.That(_source.LastDecodeTableDownload, Is.Null, "Дата файла с ftp не должна быть заполнена"); Assert.That(catalogs.Count, Is.EqualTo(0), "Таблица не должна быть заполнена"); var catalogFile = new CertificateCatalogFile(_source, DateTime.Now, Path.GetFullPath(@"..\..\Data\RostaSertList.dbf")); session.Transaction.Commit(); handler.ProcessData(); session.Refresh(_source); Assert.That(_source.LastDecodeTableDownload, Is.Not.Null, "Дата файла с ftp должна быть заполнена"); Assert.That(_source.LastDecodeTableDownload.Value.Subtract(catalogFile.FileDate).TotalSeconds, Is.LessThan(1), "Дата файла не совпадает"); var existsCatalogs = session.Query <CertificateSourceCatalog>().Where(c => c.CertificateSource == _source).ToList(); Assert.That(existsCatalogs.Count, Is.GreaterThan(0), "Таблица должна быть заполнена"); var catalogWithCatalog = existsCatalogs.Where(c => c.SupplierCode == supplierCode).FirstOrDefault(); Assert.That(catalogWithCatalog, Is.Not.Null, "Позиция не существует"); Assert.That(catalogWithCatalog.CatalogProduct, Is.Not.Null, "Позиция не сопоставлена с каталогом"); Assert.That(catalogWithCatalog.CatalogProduct.Id, Is.EqualTo(product.CatalogProduct.Id), "Позиция не сопоставлена с каталогом по значению"); var catalogWithoutCatalog = existsCatalogs.Where(c => c.SupplierCode != supplierCode).FirstOrDefault(); Assert.That(catalogWithoutCatalog, Is.Not.Null, "Позиция не существует"); Assert.That(catalogWithoutCatalog.CatalogProduct, Is.Null, "Позиция не должна быть сопоставлена с каталогом"); }
/// <summary> /// Процедура формализации /// </summary> public void ThreadWork() { ProcessState = PriceProcessState.Begin; try { using (var cleaner = new FileCleaner()) using (NDC.Push($"PriceItemId = {ProcessItem.PriceItemId}")) { //имя файла для копирования в директорию Base выглядит как: <PriceItemID> + <оригинальное расширение файла> var outPriceFileName = Path.Combine(Settings.Default.BasePath, ProcessItem.PriceItemId + Path.GetExtension(ProcessItem.FilePath)); //Используем идентификатор нитки в качестве названия временной папки var tempPath = Path.GetTempPath() + TID + "\\"; //изменяем имя файла, что оно было без недопустимых символов ('_') var tempFileName = tempPath + ProcessItem.PriceItemId + Path.GetExtension(ProcessItem.FilePath); cleaner.Watch(tempFileName); _logger.DebugFormat("Запущена нитка на обработку файла : {0}", ProcessItem.FilePath); ProcessState = PriceProcessState.CreateTempDirectory; FileHelper.InitDir(tempPath); var max = 8; for (var i = 1; i <= max; i++) { try { ProcessState = PriceProcessState.CallValidate; formalizer = PricesValidator.Validate(ProcessItem.FilePath, tempFileName, (uint)ProcessItem.PriceItemId); formalizer.Downloaded = ProcessItem.Downloaded; ProcessState = PriceProcessState.CallFormalize; formalizer.Formalize(); _log.SuccesLog(formalizer, ProcessItem.FilePath); break; } catch (MySqlException e) { if (i == max) { throw; } //Duplicate entry '%s' for key %d //всего скорее это значит что одновременно формализовался прайс-лист с такими же синонимами, нужно повторить попытку _logger.Warn($"Повторяю формализацию прайс-листа попытка {i} из {max}", e); } catch (Exception e) { var warning = (e as WarningFormalizeException) ?? (e.InnerException as WarningFormalizeException); if (warning != null) { _log.WarningLog(warning, warning.Message); break; } throw; } } FormalizeOK = true; ProcessState = PriceProcessState.FinalCopy; //Если файл не скопируется, то из Inbound он не удалиться и будет попытка формализации еще раз if (File.Exists(tempFileName)) { File.Copy(tempFileName, outPriceFileName, true); } else { File.Copy(ProcessItem.FilePath, outPriceFileName, true); } var ft = DateTime.UtcNow; File.SetCreationTimeUtc(outPriceFileName, ft); File.SetLastWriteTimeUtc(outPriceFileName, ft); File.SetLastAccessTimeUtc(outPriceFileName, ft); } } catch (ThreadAbortException e) { _logger.Warn(Settings.Default.ThreadAbortError, e); _log.ErrodLog(formalizer, new Exception(Settings.Default.ThreadAbortError)); } catch (Exception e) { if (e is DbfException || e is XmlException) { _logger.Warn("Ошибка при формализации прайс листа", e); } else { _logger.Error("Ошибка при формализации прайс листа", e); } _log.ErrodLog(formalizer, e); } finally { ProcessState = PriceProcessState.FinalizeThread; _logger.InfoFormat("Нитка завершила работу с прайсом {0}: {1}.", ProcessItem.FilePath, DateTime.UtcNow.Subtract(StartDate)); FormalizeEnd = true; } }