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); } } } } }