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 override void SendUnrecLetter(Mime m, AddressList fromList, EMailSourceHandlerException e) { try { var attachments = m.Attachments.Where(a => !String.IsNullOrEmpty(a.GetFilename())).Aggregate("", (s, a) => s + String.Format("\"{0}\"\r\n", a.GetFilename())); var ms = new MemoryStream(m.ToByteData()); FailMailSend(m.MainEntity.Subject, fromList.ToAddressListString(), m.MainEntity.To.ToAddressListString(), m.MainEntity.Date, ms, attachments, e.Message); DocumentReceiveLog.Log(GetFirmCodeByFromList(fromList), _addressId, null, _currentDocumentType.DocType, String.Format(@"{0} Тема : {1} Отправители : {2} Получатели : {3} Список вложений : {4} ", e.Message, m.MainEntity.Subject, fromList.ToAddressListString(), m.MainEntity.To.ToAddressListString(), attachments), IMAPHandler.CurrentUID); } catch (Exception exMatch) { _logger.Error("Не удалось отправить нераспознанное письмо", exMatch); } }
protected override void ErrorOnMessageProcessing(Mime m, AddressList from, EMailSourceHandlerException e) { try { var subject = e.MailTemplate.Subject; var body = e.MailTemplate.Body; var message = e.Message; if (String.IsNullOrEmpty(body)) { SendUnrecLetter(m, from, e); return; } var attachments = m.Attachments.Where(a => !String.IsNullOrEmpty(a.GetFilename())).Aggregate("", (s, a) => s + String.Format("\"{0}\"\r\n", a.GetFilename())); SendErrorLetterToSupplier(e, m); if (e is EmailFromUnregistredMail) { var mail1 = new RejectedEmail { Comment = message, LogTime = DateTime.Now, From = @from.Mailboxes.First().EmailAddress, Subject = subject }; using (var session = ActiveRecordMediator.GetSessionFactoryHolder().GetSessionFactory(typeof(ActiveRecordBase)).OpenSession()) using (var transaction = session.BeginTransaction()) { session.Save(mail1); transaction.Commit(); } } var comment = $@"{message} Отправители : {@from.ToAddressListString()} Получатели : {m.MainEntity.To.ToAddressListString()} Список вложений : {attachments} Тема письма поставщику : {subject} Тело письма поставщику : {body}"; _logger.Warn($"Не удалось разобрать письмо с адреса {@from.ToAddressListString()}", e); if (_currentDocumentType != null) { DocumentReceiveLog.Log(GetFirmCodeByFromList(@from), _addressId, null, _currentDocumentType.DocType, comment, IMAPHandler.CurrentUID); } } catch (Exception exMatch) { _logger.Error("Не удалось отправить нераспознанное письмо", exMatch); } }
protected bool ProcessWaybillFile(string inFile, DataRow drCurrent, BaseDocumentReader documentReader) { //Массив файлов var files = new[] { inFile }; var dir = inFile + ExtrDirSuffix; if (ArchiveHelper.IsArchive(inFile)) { // Получаем файлы, распакованные из архива files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories); } if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } try { files = documentReader.DivideFiles(dir, files); } catch (Exception exDivide) { var supplierId = Convert.ToUInt32(drCurrent[WaybillSourcesTable.colFirmCode]); DocumentReceiveLog.Log(supplierId, null, Path.GetFileName(CurrFileName), _currentDocumentType.DocType, String.Format("Не удалось разделить файлы: {0}", exDivide)); return(false); } var processed = false; foreach (var file in files) { if (MoveWaybill(inFile, file, drCurrent, documentReader)) { processed = true; } } return(processed); }
public override void ProcessData() { // Заполняем таблицу с данными о поставщиках. FillSourcesTable(); foreach (var row in dtSources.Rows.Cast <DataRow>()) { var supplierId = Convert.ToUInt32(row[WaybillSourcesTable.colFirmCode]); drCurrent = row; try { _currentDocumentType = null; var clazz = row[WaybillSourcesTable.colReaderClassName].ToString(); if (String.IsNullOrEmpty(clazz)) { _logger.WarnFormat("Игнорирую источник для поставщика с кодом {0} тк не задан формат разбора имени документа", supplierId); continue; } var documentReader = ReflectionHelper.GetDocumentReader <BaseDocumentReader>(clazz); foreach (var documentType in _documentTypes) { try { _currentDocumentType = documentType; // Получаем список файлов из папки var files = GetFileFromSource(supplierId, documentReader); foreach (var sourceFileName in files) { GetCurrentFile(sourceFileName); if (String.IsNullOrEmpty(CurrFileName)) { continue; } var correctArchive = PriceProcessor.FileHelper.ProcessArchiveIfNeeded(CurrFileName, ExtrDirSuffix); if (correctArchive) { if (!ProcessWaybillFile(CurrFileName, row, documentReader)) { using (var mm = new MailMessage( Settings.Default.FarmSystemEmail, Settings.Default.DocumentFailMail, String.Format("{0} ({1})", row[WaybillSourcesTable.colShortName], SourceType), String.Format("Код поставщика : {0}\nФирма: {1}\nТип: {2}\nДата: {3}\nПричина: {4}", row[WaybillSourcesTable.colFirmCode], row[SourcesTableColumns.colShortName], _currentDocumentType.GetType().Name, DateTime.Now, "Не удалось сопоставить документ клиентам. Подробнее смотрите в таблице logs.document_logs."))) { if (!String.IsNullOrEmpty(CurrFileName)) { mm.Attachments.Add(new Attachment(CurrFileName)); } var sc = new SmtpClient(Settings.Default.SMTPHost); sc.Send(mm); } } //После обработки файла удаляем его из папки if (!String.IsNullOrEmpty(sourceFileName) && File.Exists(sourceFileName)) { File.Delete(sourceFileName); } } else { DocumentReceiveLog.Log(supplierId, null, Path.GetFileName(CurrFileName), documentType.DocType, String.Format("Не удалось распаковать файл '{0}'", Path.GetFileName(CurrFileName))); //Распаковать файл не удалось, поэтому удаляем его из папки if (!String.IsNullOrEmpty(sourceFileName) && File.Exists(sourceFileName)) { File.Delete(sourceFileName); } } Cleanup(); } } catch (Exception e) { //Обрабатываем ошибку в случае обработки одного из типов документов var message = String.Format("Источник : {0}\nТип : {1}", supplierId, documentType.GetType().Name); Log(e, message); } } } catch (Exception ex) { Log(ex, String.Format("Источник : {0}", supplierId)); } } }
protected override void ProcessAttachs(Mime mime, AddressList fromList) { //Один из аттачментов письма совпал с источником, иначе - письмо не распознано bool matched = false; /* * В накладных письма обрабатываются немного по-другому: * письма обрабатываются относительно адреса отправителя * и если такой отправитель найден в истониках, то все вложения * сохраняются относительно него. * Если он не найден, то ничего не делаем. */ if (fromList == null) { _logger.Info("WaybillEmailSourceHandler: Адрес отправителя пуст"); } if (fromList.Count == 0) { _logger.Info("WaybillEmailSourceHandler: Адреса в коллекции не обнаружены"); } if (fromList.Mailboxes.Length == 0) { _logger.Info("WaybillEmailSourceHandler: Список адресов mailboxes пустой"); } foreach (var mbFrom in fromList.Mailboxes) { var sources = dtSources.Select(String.Format("({0} like '*{1}*')", WaybillSourcesTable.colEMailFrom, mbFrom.EmailAddress)); // Адрес отправителя должен быть только у одного поставщика, // если получилось больше, то ищем поставщика, который доступен клиенту, // если таких нет или несколько, то это ошибка DataRow source; if (sources.Length > 1) { source = SelectWaybillSourceForClient(sources, _addressId); if (source == null) { _logger.Info(String.Format("WaybillEmailSourceHandler: На адрес \"{0}\"" + "назначено несколько поставщиков. Определить какой из них работает с клиентом не удалось", mbFrom.EmailAddress)); throw new Exception(String.Format( "На адрес \"{0}\" назначено несколько поставщиков. Определить какой из них работает с клиентом не удалось", mbFrom.EmailAddress)); } } else if (sources.Length == 0) { var addition = dtSources.Rows == null ? "В строках источников находится null" : String.Format("Количество записей в источниках - {0}", dtSources.Rows.Count); _logger.Info(String.Format("WaybillEmailSourceHandler: Не найдено записи в источниках, соответствующей адресу {0}. {1}", mbFrom.EmailAddress, addition)); if (dtSources.Rows != null && dtSources.Rows.Count > 0) { var count1 = dtSources.Select(String.Format("({0} like '*{1}*')", WaybillSourcesTable.colEMailFrom, mbFrom.EmailAddress)).Length; var count2 = dtSources.Select(String.Format("({0} like '%{1}%')", WaybillSourcesTable.colEMailFrom, mbFrom.EmailAddress)).Length; _logger.Info(String.Format("WaybillEmailSourceHandler: Делаем попытку выбрать нужные записи иначе: " + "количество через * - {0}, через % - {1}, исходное - {2}", count1, count2, sources.Count())); } continue; } else { source = sources.Single(); } var attachments = mime.GetValidAttachements(); if (!attachments.Any()) { _logger.Info(String.Format("WaybillEmailSourceHandler: Отсутствуют вложения в письме от адреса {0}", mbFrom.EmailAddress)); } //двойная очистка FileCleaner и Cleanup нужно оставить только одно //думаю Cleaner подходит лучше using (var cleaner = new FileCleaner()) { var savedFiles = new List <string>(); foreach (var entity in attachments) { SaveAttachement(entity); var correctArchive = FileHelper.ProcessArchiveIfNeeded(CurrFileName, ExtrDirSuffix); matched = true; if (!correctArchive) { DocumentReceiveLog.Log(Convert.ToUInt32(source[WaybillSourcesTable.colFirmCode]), _addressId, Path.GetFileName(CurrFileName), _currentDocumentType.DocType, "Не удалось распаковать файл", IMAPHandler.CurrentUID); Cleanup(); continue; } if (ArchiveHelper.IsArchive(CurrFileName)) { var files = Directory.GetFiles(CurrFileName + ExtrDirSuffix + Path.DirectorySeparatorChar, "*.*", SearchOption.AllDirectories); savedFiles.AddRange(files); cleaner.Watch(files); } else { savedFiles.Add(CurrFileName); cleaner.Watch(CurrFileName); } } var logs = ProcessWaybillFile(savedFiles, source); var service = new WaybillService(); service.Process(logs); if (service.Exceptions.Count > 0) { SendErrorLetterToSupplier(service.Exceptions.First(), mime); } } Cleanup(); source.Delete(); dtSources.AcceptChanges(); } //foreach (MailboxAddress mbFrom in FromList.Mailboxes) if (!matched) { throw new EmailFromUnregistredMail( "Для данного E-mail не найден источник в таблице documents.waybill_sources", Settings.Default.ResponseDocSubjectTemplateOnUnknownProvider, Settings.Default.ResponseDocBodyTemplateOnUnknownProvider); } }