public void Process_message_if_from_contains_more_than_one_address() { client = TestClient.CreateNaked(session); address = client.Addresses[0]; supplier = TestSupplier.CreateNaked(session); supplier.WaybillSource.EMailFrom = String.Format("edata{0}@msk.katren.ru", supplier.Id); supplier.WaybillSource.SourceType = TestWaybillSourceType.Email; session.Save(supplier); FileHelper.DeleteDir(Settings.Default.DocumentPath); ImapHelper.ClearImapFolder(); var mime = PatchTo(@"..\..\Data\Unparse.eml", String.Format("{0}@waybills.analit.net", address.Id), String.Format("edata{0}@msk.katren.ru,[email protected]", supplier.Id)); ImapHelper.StoreMessage(mime.ToByteData()); Process(); var files = GetFileForAddress(DocType.Waybill); Assert.That(files.Length, Is.EqualTo(1), "не обработали документ"); }
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, "Позиция не должна быть сопоставлена с каталогом"); }
public override string[] UnionFiles(string[] InputFiles) { var inputList = new List <string>(InputFiles); var outputList = new List <string>(); while (inputList.Count > 0) { var shortName = Path.GetFileName(inputList[0]); if (shortName.EndsWith(".dbf", StringComparison.OrdinalIgnoreCase) && (shortName.StartsWith("b_", StringComparison.OrdinalIgnoreCase) || shortName.StartsWith("h_", StringComparison.OrdinalIgnoreCase))) { var doubleName = Path.GetFileNameWithoutExtension(shortName).Substring(2); if (shortName.StartsWith("b_", StringComparison.OrdinalIgnoreCase)) { doubleName = "h_" + doubleName + ".dbf"; } else { doubleName = "b_" + doubleName + ".dbf"; } //Попытка найти пару к файлу var originalDoubleName = inputList.Find(s => s.Equals(Path.GetDirectoryName(inputList[0]) + Path.DirectorySeparatorChar + doubleName, StringComparison.OrdinalIgnoreCase)); //Если нашли, то архивируем оба файла, если не нашли и файл создан давно, то архивируем один файл if (originalDoubleName != default(string)) { FileHelper.ClearReadOnly(inputList[0]); FileHelper.ClearReadOnly(originalDoubleName); //todo: filecopy здесь происходит копирование полученных файлов во временную папку для дальнейшего разбора ситуации, из-за предположения, что есть проблема с пропажей документов var archiveFileName = ArhiveFiles(new[] { inputList[0], originalDoubleName }); outputList.Add(archiveFileName); File.Delete(inputList[0]); File.Delete(originalDoubleName); inputList.Remove(originalDoubleName); } else if (DateTime.Now.Subtract(File.GetLastWriteTime(inputList[0])).TotalMinutes > 6 * Settings.Default.FileDownloadInterval) { //Ждали пару к файлу, но так и не дождались outputList.Add(ArhiveFiles(new[] { inputList[0] })); File.Delete(inputList[0]); } inputList.RemoveAt(0); } else { //Если это не документы накладных, то просто добавляем их в результирующий список outputList.Add(inputList[0]); inputList.RemoveAt(0); } } return(outputList.ToArray()); }
private void GetCurrentFile(string sourceFile) { CurrFileName = String.Empty; var destination = DownHandlerPath + Path.GetFileName(sourceFile); try { if (File.Exists(destination)) { File.Delete(destination); } FileHelper.ClearReadOnly(sourceFile); File.Copy(sourceFile, destination); CurrFileName = destination; } catch (Exception ex) { Log(ex, String.Format("Не удалось скопировать файл {0} в {1}", sourceFile, destination)); } }
public static void RecreateDirectories() { var dirs = new[] { Settings.Default.BasePath, Settings.Default.ErrorFilesPath, Settings.Default.InboundPath, Settings.Default.TempPath, Settings.Default.HistoryPath, Settings.Default.FTPOptBoxPath, Settings.Default.DownWaybillsPath, Settings.Default.DocumentPath, Settings.Default.CertificatePath, Settings.Default.AttachmentPath }; dirs.Each(d => { if (Directory.Exists(d)) { FileHelper.DeleteDir(d); } Directory.CreateDirectory(d); }); }
/// <summary> /// Забирает файлы из фтп директории, сохраняет их локально и возвращает список локальных путей для этих файлов. /// Если при получении какого-то файла произошла ошибка, то пытается получить этот файл еще 2 раза, если не удалось, /// тогда имя этого файла добавляется в список FailedFiles. /// </summary> /// <param name="ftpHost">Имя хоста</param> /// <param name="ftpPort">Номер порта</param> /// <param name="ftpDirectory">Директория</param> /// <param name="username">Логин</param> /// <param name="password">Пароль</param> /// <param name="fileMask">Маска имени файла (на соответствие маске проверяется каждый файл)</param> /// <param name="lastDownloadTime">Время, когда была последняя загрузка</param> /// <param name="downloadDirectory">Директория, куда будут сохранены загруженные файлы</param> /// <param name="ftpPassiveMode">Пассивный режим для ftp-клиента</para> /// <returns>Список файлов, сохраненных локально</returns> public IList <DownloadedFile> GetFilesFromSource(string ftpHost, int ftpPort, string ftpDirectory, string username, string password, string fileMask, DateTime lastDownloadTime, string downloadDirectory, bool ftpPassiveMode = true) { var uri = new UriBuilder(ftpHost); ftpHost = uri.Host; if (!ftpDirectory.StartsWith(@"/", StringComparison.OrdinalIgnoreCase)) { ftpDirectory = @"/" + ftpDirectory; } var receivedFiles = new List <DownloadedFile>(); using (var ftpClient = new FTP_Client()) { var url = String.Format("ftp://{0}@{1}:{2}{3}/{4}", username, ftpHost, ftpPort, ftpDirectory, fileMask); _log.DebugFormat("Загрузка файлов с {0}", url); var dataSetEntries = GetFtpFilesAndDirectories(ftpClient, ftpHost, ftpPort, username, password, ftpDirectory, ftpPassiveMode); foreach (DataRow entry in dataSetEntries.Tables["DirInfo"].Rows) { if (Convert.ToBoolean(entry["IsDirectory"])) { continue; } var fileInDirectory = entry["Name"].ToString(); // Если файл не подходит по маске, берем следующий if (!PriceProcessor.FileHelper.CheckMask(fileInDirectory, fileMask)) { continue; } var fileWriteTime = Convert.ToDateTime(entry["Date"]); #if DEBUG if (UseStub) { lastDownloadTime = DateTime.Now.AddMonths(-1); } #endif if (((fileWriteTime.CompareTo(lastDownloadTime) > 0) && (DateTime.Now.Subtract(fileWriteTime).TotalMinutes > Settings.Default.FileDownloadInterval)) || ((fileWriteTime.CompareTo(DateTime.Now) > 0) && (fileWriteTime.Subtract(lastDownloadTime).TotalMinutes > 0))) { var downloadedFile = Path.Combine(downloadDirectory, fileInDirectory); try { #if !DEBUG ReceiveFile(ftpClient, fileInDirectory, downloadedFile); #else if (UseStub) { // Для тестов if (ftpDirectory.StartsWith(@"/", StringComparison.OrdinalIgnoreCase)) { ftpDirectory = ftpDirectory.Substring(1); } var path = Path.Combine(Settings.Default.FTPOptBoxPath, ftpDirectory); File.Copy(Path.Combine(path, fileInDirectory), downloadedFile, true); } else { ReceiveFile(ftpClient, fileInDirectory, downloadedFile); } #endif receivedFiles.Add(new DownloadedFile(downloadedFile, fileWriteTime)); FileHelper.ClearReadOnly(downloadedFile); } catch (Exception e) { _log.Debug(String.Format("Ошибка при попытке загрузить файл {0}", url), e); } } else { _log.DebugFormat("Файл {0} уже забран и дата файла еще не обновлена. Не забираем.", fileInDirectory); } } } return(receivedFiles); }
/// <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; } }