public void ProcessFile(InboundDocumentType documentType, WaybillSource waybillSource, DownloadedFile downloadedFile)
        {
            var logs = ProcessWaybill(documentType.DocType, waybillSource, downloadedFile);

            // Обработка накладной(или отказа), помещение ее в папку клиенту
            new WaybillService().Process(logs);
        }
Ejemplo n.º 2
0
        public Uri Uri(InboundDocumentType documentType)
        {
            string data = null;

            if (documentType is WaybillType)
            {
                data = WaybillUrl;
            }
            if (documentType is RejectType)
            {
                data = RejectUrl;
            }
            if (String.IsNullOrEmpty(data))
            {
                return(null);
            }

            var uri = new Uri(data, UriKind.RelativeOrAbsolute);

            if (!uri.IsAbsoluteUri)
            {
                uri = new UriBuilder("ftp" + System.Uri.SchemeDelimiter + data).Uri;
            }
            return(uri);
        }
        public override void CheckMime(Mime m)
        {
            _addressId           = null;
            _currentDocumentType = null;

            // Получаем кол-во корректных адресов, т.е. отправленных
            // на @waybills.analit.net или на @refused.analit.net
            var emailList = m.GetRecipients()
                            .Where(x => GetClientCode(x) != null)
                            .Select(s => s.ToUpper())
                            .Distinct()
                            .ToList();

            var correctAddresCount = emailList.Count;

            // Все хорошо, если кол-во вложений больше 0 и распознан только один адрес как корректный
            // Если не сопоставили с клиентом)
            if (correctAddresCount == 0)
            {
                throw new EMailSourceHandlerException("Не найден клиент.",
                                                      Settings.Default.ResponseDocSubjectTemplateOnNonExistentClient,
                                                      Settings.Default.ResponseDocBodyTemplateOnNonExistentClient);
            }
            if (correctAddresCount == 1 && m.Attachments.Length == 0)
            {
                throw new EMailSourceHandlerException("Письмо не содержит вложений.",
                                                      Settings.Default.ResponseDocSubjectTemplateOnNothingAttachs,
                                                      Settings.Default.ResponseDocBodyTemplateOnNothingAttachs);
            }
            if (correctAddresCount > 1)
            {
                throw new EMailSourceHandlerException("Письмо отправленно нескольким клиентам.",
                                                      Settings.Default.ResponseDocSubjectTemplateOnMultiDomen,
                                                      Settings.Default.ResponseDocBodyTemplateOnMultiDomen);
            }
            if (m.Attachments.Length > 0)
            {
                var attachmentsIsBigger = m.Attachments.Any(attachment => (attachment.Data.Length / 1024.0) > Settings.Default.MaxWaybillAttachmentSize);
                if (attachmentsIsBigger)
                {
                    throw new EMailSourceHandlerException(String.Format("Письмо содержит вложение размером больше максимально допустимого значения ({0} Кб).",
                                                                        Settings.Default.MaxWaybillAttachmentSize),
                                                          Settings.Default.ResponseDocSubjectTemplateOnMaxWaybillAttachment,
                                                          String.Format(Settings.Default.ResponseDocBodyTemplateOnMaxWaybillAttachment,
                                                                        Settings.Default.MaxWaybillAttachmentSize));
                }
            }
        }
        private void LogError(Exception e, WaybillSource source, Uri uri, InboundDocumentType documentType)
        {
            var errorMessage = String.Format("Ошибка при попытке забрать документы с FTP поставщика (код поставщика: {0}).\nТип документов: {1}.\nUrl: {2}",
                                             source.Id,
                                             documentType.DocType.GetDescription(),
                                             uri);

            if (!_failedSources.Contains(source.Id))
            {
                _failedSources.Add(source.Id);
                _logger.Warn(errorMessage, e);
            }
            else
            {
                _logger.Debug(errorMessage, e);
            }
        }
        /// <summary>
        /// Извлекает код клиента (или код адреса клиента) из email адреса,
        /// на который поставщик отправил накладную (или отказ)
        /// </summary>
        /// <returns>Если код извлечен и соответствует коду клиента
        /// (или коду адреса), будет возвращен этот код.
        /// Если код не удалось извлечь или он не найден ни среди кодов клиентов,
        /// ни среди кодов адресов, будет возвращен null</returns>
        private uint?GetClientCode(string emailAddress)
        {
            emailAddress = emailAddress.ToLower();
            InboundDocumentType testType = null;
            uint?addressId = null;

            foreach (var documentType in _documentTypes)
            {
                uint clientCode;

                // Пытаемся извлечь код клиента из email адреса
                if (documentType.ParseEmail(emailAddress, out clientCode))
                {
                    addressId = clientCode;
                    testType  = documentType;
                    break;
                }
            }

            if (testType != null)
            {
                if (ClientExists(addressId.Value))
                {
                    if (_currentDocumentType == null)
                    {
                        _currentDocumentType = testType;
                        _addressId           = addressId;
                    }
                }
                else
                {
                    addressId = null;
                }
            }

            return(addressId);
        }
        private void ReceiveDocuments(InboundDocumentType documentType, WaybillSource waybillSource, Uri uri)
        {
            var haveErrors = false;

            if (uri == null)
            {
                return;
            }

            _logger.InfoFormat("Попытка получения документов с FTP поставщика (код поставщика: {0}).\nТип документов: {1}.\nUrl: {2}",
                               waybillSource.Id,
                               documentType.DocType.GetDescription(),
                               uri);

            try {
                using (var ftpClient = waybillSource.CreateFtpClient()) {
                    ftpClient.Connect(uri.Host, uri.Port);
                    ftpClient.Authenticate(waybillSource.UserName, waybillSource.Password);
                    ftpClient.SetCurrentDir(uri.PathAndQuery);

                    var files = ftpClient.GetList();
                    foreach (var file in files.Tables["DirInfo"].AsEnumerable())
                    {
                        if (Convert.ToBoolean(file["IsDirectory"]))
                        {
                            continue;
                        }

                        Cancellation.ThrowIfCancellationRequested();

                        var source       = file["Name"].ToString();
                        var sourceDate   = Convert.ToDateTime(file["Date"]);
                        var sourceLength = Convert.ToInt64(file["Size"]);
                        var dest         = Path.Combine(DownHandlerPath, source);
                        try {
                            ftpClient.ReceiveFile(source, dest);
                            var destLenth = new FileInfo(dest).Length;
                            if (destLenth != sourceLength)
                            {
                                _logger.WarnFormat("Не совпадает размер загруженного файла {0} {1} размер на ftp {2} полученный рамер {3}",
                                                   uri,
                                                   source,
                                                   sourceLength,
                                                   destLenth);
                                continue;
                            }

                            var downloadedFile = new DownloadedFile(dest, sourceDate);

                            ProcessFile(documentType, waybillSource, downloadedFile);

                            ftpClient.DeleteFile(source);
                        }
                        catch (Exception e) {
                            haveErrors = true;
                            LogError(e, waybillSource, uri, documentType);
                        }
                    }
                }

                if (!haveErrors && _failedSources.Contains(waybillSource.Id))
                {
                    waybillSource.LastError = DateTime.Now;
                    _failedSources.Remove(waybillSource.Id);
                    _logger.WarnFormat("После возникновения ошибок загрузка накладных прошла успешно. Код поставщика: {0}", waybillSource.Id);
                }
            }
            catch (Exception e) {
                LogError(e, waybillSource, uri, documentType);
            }
        }
        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));
                }
            }
        }