protected bool MoveWaybill(string archFileName, string fileName, DataRow drCurrent, BaseDocumentReader documentReader) { using (var cleaner = new FileCleaner()) { var supplierId = Convert.ToUInt32(drCurrent[WaybillSourcesTable.colFirmCode]); try { var addresses = With.Connection(c => documentReader.ParseAddressIds(c, supplierId, archFileName, fileName)); var formatFile = documentReader.FormatOutputFile(fileName, drCurrent); cleaner.Watch(fileName); cleaner.Watch(formatFile); foreach (var addressId in addresses) { var log = DocumentReceiveLog.LogNoCommit(supplierId, (uint)addressId, formatFile, _currentDocumentType.DocType, "Получен с нашего FTP"); _logger.InfoFormat("WaybillLanSourceHandler: обработка файла {0}", fileName); documentReader.ImportDocument(log, fileName); new WaybillService().Process(new[] { log }.ToList()); } } catch (Exception e) { var message = "Не удалось отформатировать документ.\nОшибка: " + e; _logger.ErrorFormat("WaybillLanSourceHandler: {0}, archfilename {1}, fileName {2}, error {3}", message, archFileName, fileName, e); DocumentReceiveLog.Log(supplierId, null, fileName, _currentDocumentType.DocType, message); return(false); } } return(true); }
protected DocumentReceiveLog GetLog(string file, DataRow source) { _logger.InfoFormat("WaybillEmailSourceHandler: обработка файла {0}", file); var supplierId = Convert.ToUInt32(source[WaybillSourcesTable.colFirmCode]); return(DocumentReceiveLog.LogNoCommit( supplierId, _addressId, file, _currentDocumentType.DocType, "Получен по Email", IMAPHandler.CurrentUID)); }
private List <DocumentReceiveLog> ProcessWaybill(DocType documentType, WaybillSource source, DownloadedFile downloadedFile) { var documentLogs = new List <DocumentReceiveLog>(); var reader = new SupplierFtpReader(); var addressIds = With.Connection(c => reader.ParseAddressIds(c, source.Id, downloadedFile.FileName, downloadedFile.FileName)); foreach (var addressId in addressIds) { // Если накладная - это архив, разархивируем логируем каждый файл и копируем в папку клиенту var waybillFiles = new[] { downloadedFile.FileName }; try { waybillFiles = FileHelper.TryExtractArchive(downloadedFile.FileName, downloadedFile.FileName + BaseSourceHandler.ExtrDirSuffix) ?? waybillFiles; } catch (ArchiveHelper.ArchiveException e) { _logger.Warn($"Ошибка при извлечении файлов из архива {downloadedFile.FileName}", e); WaybillService.SaveWaybill(downloadedFile.FileName); continue; } foreach (var file in waybillFiles) { var isNew = IsNewWaybill(source, (uint)addressId, Path.GetFileName(file), new FileInfo(file).Length); if (!isNew) { _logger.DebugFormat("Файл {0} не является новой накладной, не обрабатываем его", file); continue; } var log = DocumentReceiveLog.LogNoCommit(source.Id, (uint)addressId, file, documentType, "Получен с клиентского FTP"); _logger.InfoFormat("WaybillFtpSourceHandler: обработка файла {0}", file); documentLogs.Add(log); } } return(documentLogs); }
public void ProcessMessage(ISession session, MimeMessage message, UniqueId messageId = default(UniqueId)) { //используется промежуточный почтовый ящик для транзита //в поле To будет именно он, этот же ящик используется для транзита прайс-листов var emails = message.To.OfType <MailboxAddress>().Where(s => !string.IsNullOrEmpty(s.Address)).Select(a => a.Address).ToArray(); if (emails.Length == 0) { NotifyAdmin("У сообщения не указано ни одного получателя.", message); return; } var attachments = message.Attachments.Where(m => !String.IsNullOrEmpty(GetFileName(m)) && m.IsAttachment); if (!attachments.Any()) { NotifyAdmin($"Отсутствуют вложения в письме от адреса {message.To.Implode()}", message); return; } var dtSources = session.Connection.Query <SupplierSelector>(@" SELECT distinct s.Id as FirmCode, st.EMailTo FROM farm.sourcetypes join farm.Sources as st on st.SourceTypeId = sourcetypes.Id join usersettings.PriceItems pi on pi.SourceId = st.ID join usersettings.PricesCosts pc on pc.PriceItemId = pi.ID join UserSettings.PricesData as PD on PD.PriceCode = pc.PriceCode join Customers.Suppliers as s on s.Id = PD.FirmCode WHERE sourcetypes.Type = 'EMail' and s.Disabled = 0 and pd.AgencyEnabled = 1" ).ToList(); var sources = emails .SelectMany(x => dtSources.Where(y => y.EmailTo?.IndexOf(x, StringComparison.OrdinalIgnoreCase) >= 0)) .Distinct() .ToList(); if (sources.Count > 1) { NotifyAdmin( $"Для получателей {emails.Implode()} определено более одного поставщика." + $" Определенные поставщики {sources.Select(x => x.FirmCode).Implode()}.", message); return; } if (sources.Count == 0) { NotifyAdmin( $"Не удалось идентифицировать ни одного поставщика по адресам получателя {emails.Implode()}." + $" Количество записей в источниках - {dtSources.Count}", message); return; } var source = sources.First(); var supplierId = source.FirmCode; var supplier = session.Load <Supplier>(supplierId); using (var cleaner = new FileCleaner()) { foreach (var mimeEntity in attachments) { //получение текущей директории var filename = Path.Combine(DownHandlerPath, GetFileName(mimeEntity)); var files = new List <string> { filename }; //сохранение содержимого в текущую директорию using (var fs = new FileStream(filename, FileMode.Create)) ((MimePart)mimeEntity).ContentObject.DecodeTo(fs); try { files = FileHelper.TryExtractArchive(filename, cleaner.RandomDir())?.ToList() ?? files; } catch (ArchiveHelper.ArchiveException e) { _logger.Warn($"Не удалось распаковать файл {filename}", e); NotifyAdmin($"Не удалось распаковать файл {filename}.", message, supplier); continue; } var logs = new List <DocumentReceiveLog>(); foreach (var file in files) { //нам нужно считать файл что бы узнать кто его отправил, по хорошему нам и не нужен пока что клиент var doc = new WaybillFormatDetector().Parse(session, file, new DocumentReceiveLog(supplier, new Address(new Client()), DocType.Waybill)); if (doc == null) { NotifyAdmin($"Не удалось разобрать документ {file} нет подходящего формата.", message, supplier); continue; } if (doc.Invoice?.RecipientId == null) { if (doc.Parser == nameof(WaybillSstParser)) { NotifyAdmin($"В файле {file} не заполнено поле Код получателя.", message, supplier); } else { NotifyAdmin($"Формат файла {file} не соответствует согласованному формату sst. " + $"Поле 'Код получателя' не заполнено, возможно выбранный формат {doc.Parser} не считывает поле либо оно не заполнено в файла. " + $"Проверьте настройки формата {doc.Parser} и заполнение поля 'Код получателя' в файле.", message, supplier); } continue; } var result = session.Connection.Query <uint?>(@" select ai.AddressId from Customers.Intersection i join Customers.AddressIntersection ai on ai.IntersectionId = i.Id join Usersettings.Pricesdata pd on pd.PriceCode = i.PriceId join Customers.Suppliers s on s.Id = pd.FirmCode where ai.SupplierDeliveryId = @supplierDeliveryId and s.Id = @supplierId group by ai.AddressId", new { @supplierDeliveryId = doc.Invoice.RecipientId, @supplierId = supplierId }) .FirstOrDefault(); if (result == null) { NotifyAdmin($"Не удалось обработать документ {file} для кода получателя {doc.Invoice.RecipientId} не найден адрес доставки. " + $"Проверьте заполнение поля 'Код адреса доставки' в личном кабинете поставщика {supplierId}.", message, supplier); continue; } _logger.InfoFormat($"Файл {file} обработан для кода получателя {doc.Invoice.RecipientId} выбран адрес {result.Value}"); logs.Add(DocumentReceiveLog.LogNoCommit(supplierId, result.Value, file, DocType.Waybill, "Получен по Email", (int?)messageId.Id)); } //если логи есть, значит файл распознан и найден соответствующий адрес доставки if (logs.Count > 0) { var service = new WaybillService(); service.Process(logs); if (service.Exceptions.Count > 0) { NotifyAdmin(service.Exceptions.First().Message, message, supplier); } } } } }