//Создание задачи с файлом для Redmine (в сообщении задачи метаданные логов по документа в формате json) public static MetadataOfLog CreateIssueWithAFile(string subject, DocumentReceiveLog log, bool hasPriority) { RedmineFile fileOnRedmine = null; var fi = new FileInfo(log.GetFileName()); if (!hasPriority && fi.Extension.ToLower() != ".dbf") { return(null); } var redmineProject = hasPriority ? Settings.Default.RedmineProjectForWaybillIssueWithPriority : Settings.Default.RedmineProjectForWaybillIssue; var redmineUser = !hasPriority || fi.Extension.ToLower() == ".dbf" ? Settings.Default.RedmineAssignedTo : Settings.Default.RedmineAssignedToWithPriority; var bufferF = File.ReadAllBytes(fi.FullName); var currentMeta = new MetadataOfLog(log); #if DEBUG //для тестов if (!FileAlreadyInIssue(redmineProject, currentMeta.Hash)) { var debugHash = log.FileName.GetHashCode().ToString().Replace("-", ""); var token = debugHash; #else if (!FileAlreadyInIssue(redmineProject, currentMeta.Hash)) { var token = UploadFileToRedmine( string.Format(Settings.Default.RedmineUrlFileUpload, Settings.Default.RedmineKeyForWaybillIssue), bufferF); #endif if (token != string.Empty) { fileOnRedmine = new RedmineFile { Token = token, Content_type = "application/binary", Filename = fi.Name, Json = $"Служебная информация по {(log.DocumentType == DocType.Waybill ? "накладной" : "отказу")}: {currentMeta.Hash}" }; //возвращаем метаданные только, если задача создана return (CreateIssue( string.Format(Settings.Default.RedmineUrl, redmineProject, Settings.Default.RedmineKeyForWaybillIssue), subject, fileOnRedmine.Json, redmineUser , new List <RedmineFile> { fileOnRedmine }) ? currentMeta : null); } } return(null); }
/// <summary> /// Создание отказа из лога приемки документа /// </summary> /// <param name="log">Объект лога документа</param> /// <returns></returns> public RejectHeader CreateReject(DocumentReceiveLog log) { BadLines = new List <RejectLine>(); var rejectheader = new RejectHeader(log); var filename = log.GetFileName(); Parse(rejectheader, filename); rejectheader.Parser = this.GetType().Name; CheckRejectHeader(rejectheader); return(rejectheader); }
private string CopyToRightDirrectory(DocumentReceiveLog log) { var fi = new FileInfo(log.GetFileName()); var str = fi.DirectoryName; if (!Directory.Exists(str)) { Directory.CreateDirectory(str); } File.Delete(fi.FullName); File.Copy(log.FileName, fi.FullName); return(Directory.GetParent(str).FullName); }
public static IList <DocumentForParsing> Merge(List <DocumentReceiveLog> documents) { DocumentReceiveLog headerFile = null; DocumentReceiveLog bodyFile = null; try { var resultList = new List <DocumentForParsing>(); for (var i = 0; i < documents.Count; i++) { headerFile = null; bodyFile = null; var file = documents[i]; if (IsHeaderFile(file)) { headerFile = file; bodyFile = GetSecondFile(headerFile, documents); } if (IsBodyFile(file)) { bodyFile = file; headerFile = GetSecondFile(bodyFile, documents); } if ((headerFile != null) && (bodyFile != null)) { var mergedFile = MergeFiles(headerFile, bodyFile); resultList.Add(new DocumentForParsing(file, mergedFile)); documents.Remove(headerFile); documents.Remove(bodyFile); i--; } else { resultList.Add(new DocumentForParsing(file)); } } return(resultList); } catch (Exception e) { var log = LogManager.GetLogger(typeof(MultifileDocument)); log.Error("Ошибка при слиянии многофайловых накладных", e); if (headerFile != null) { WaybillService.SaveWaybill(headerFile.GetFileName()); } if (bodyFile != null) { WaybillService.SaveWaybill(bodyFile.GetFileName()); } return(documents.Select(d => new DocumentForParsing(d)).ToList()); } }
public static RejectHeader Parse(DocumentReceiveLog log, List <RejectDataParser> parsers) { var filePath = log.GetFileName(); if (!Path.GetExtension(filePath).Match(".dbf")) { return(null); } DataTable table; try { table = Dbf.Load(filePath); } catch (Exception e) { Log.Warn($"Не удалось разобрать документ {filePath} номер входящего документа {log.Id}", e); return(null); } var columns = table.Columns.Cast <DataColumn>().Select(x => x.ColumnName).ToArray(); foreach (var parser in parsers) { if (columns.Intersect(parser.Lines.Select(x => x.Src), StringComparer.CurrentCultureIgnoreCase).Count() != parser.Lines.Count) { continue; } var reject = new RejectHeader(log); foreach (var dataRow in table.AsEnumerable()) { var docLine = new RejectLine(); foreach (var parserLine in parser.Lines) { var propertyName = parserLine.Dst; if (String.IsNullOrEmpty(propertyName) || String.IsNullOrEmpty(parserLine.Src)) { continue; } var property = docLine.GetType().GetProperty(propertyName); var value = DbfParser.ConvertIfNeeded(dataRow[parserLine.Src], property.PropertyType); property.SetValue(docLine, value); } docLine.Header = reject; reject.Lines.Add(docLine); } reject.Parser = parser.Name; return(reject); } return(null); }
private static string MergeFiles(DocumentReceiveLog headerFile, DocumentReceiveLog bodyFile) { var tableHeader = Dbf.Load(headerFile.GetFileName()); var tableBody = Dbf.Load(bodyFile.GetFileName()); var commonColumns = new List <string>(); foreach (DataColumn column in tableHeader.Columns) { if (tableBody.Columns.Contains(column.ColumnName)) { commonColumns.Add(column.ColumnName); } else { tableBody.Columns.Add(column.ColumnName); } } var headerColumnName = String.Empty; var bodyColumnName = String.Empty; if (commonColumns.Count != 1) { headerColumnName = "DOCNUMBER"; if (!tableHeader.Columns.Contains(headerColumnName)) { headerColumnName = "DOCNUM"; } bodyColumnName = "DOCNUMDER"; if (!tableBody.Columns.Contains(bodyColumnName)) { bodyColumnName = "DOCNUMBER"; } } else { headerColumnName = commonColumns[0]; bodyColumnName = commonColumns[0]; } if (!tableHeader.Columns.Contains(headerColumnName) || !tableBody.Columns.Contains(bodyColumnName)) { throw new Exception(String.Format(@" При объединении двух DBF файлов возникла ошибка. Количество общих колонок отличается от 1 и нет колонок {2} или {3}. Файл-заголовок: {0} Файл-тело: {1}", headerFile.FileName, bodyFile.FileName, headerColumnName, bodyColumnName)); } foreach (DataRow headerRow in tableHeader.Rows) { foreach (DataRow bodyRow in tableBody.Rows) { if (!headerRow[headerColumnName].Equals(bodyRow[bodyColumnName])) { continue; } foreach (DataColumn column in tableHeader.Columns) { if (commonColumns.Contains(column.ColumnName)) { continue; } bodyRow[column.ColumnName] = headerRow[column.ColumnName]; } } } tableBody.AcceptChanges(); // Path.GetFileName(headerFilePath).Substring(1) потому что первая буква "h" нам не нужна var mergedFileName = Path.Combine(Path.GetTempPath(), MergedPrefix + Path.GetFileName(headerFile.FileName).Substring(1)); if (File.Exists(mergedFileName)) { File.Delete(mergedFileName); } Dbf.Save(tableBody, mergedFileName); return(mergedFileName); }
/// <summary> /// Создание отказов для логов. /// </summary> /// <param name="session">Сессия Nhibernate</param> /// <param name="log">Лог, о получении документа</param> /// <param name="metaForRedmineErrorIssueList"></param> private static void ProcessReject(ISession session, DocumentReceiveLog log, List <MetadataOfLog> metaForRedmineErrorIssueList) { RejectHeader reject; //если есть назначенные поставщику правила разбора var parsers = session.Query <RejectDataParser>().Where(x => x.Supplier.Id == log.Supplier.Id).ToList(); //попытка распарсить ими reject = RejectDataParser.Parse(log, parsers); //иначе, выбор из имеющихся парсеров if (reject == null) { var parser = GetRejectParser(log); if (parser == null) { if (log.DocumentType == DocType.Reject) { //создаем задачу на Redmine, прикрепляя файлы Redmine.CreateIssueForLog(ref metaForRedmineErrorIssueList, log); } return; } reject = parser.CreateReject(log); if (reject == null) { if (log.DocumentType == DocType.Reject) { //создаем задачу на Redmine, прикрепляя файлы Redmine.CreateIssueForLog(ref metaForRedmineErrorIssueList, log); } return; } } if (reject.Lines.Count > 0) { try { reject.Normalize(session); } catch (Exception e) { _log.Error(string.Format("Не удалось идентифицировать товары отказа {0}", log.GetFileName()), e); } session.Save(reject); } }
private DocumentReceiveLog ParseFileForRedmine(string filename, bool createIssue = true, bool changeValues = true, DocType documentType = DocType.Waybill, bool deleteCreatedDirectory = true, bool priority = false, bool priorityFull = true, bool exceptionAdd = false) { var addressRed = session.Query <Address>() .FirstOrDefault( s => (changeValues && s.Id != testAddress.Id) || (!changeValues && s.Id == testAddress.Id)); var supplierRed = session.Query <Supplier>() .FirstOrDefault(s => (changeValues && s.Id != supplier.Id) || (!changeValues && s.Id == supplier.Id)); supplierRed.RegionMask = addressRed.Client.MaskRegion; session.Save(supplierRed); if (exceptionAdd) { if (!session.Transaction.IsActive) { session.BeginTransaction(); } session.Transaction.Commit(); session.BeginTransaction(); session.Connection.Query( $"INSERT INTO usersettings.WaybillExcludeFile (Supplier,Mask) Values({supplierRed.Id} , '{"*.dbf"}')") .FirstOrDefault(); session.Transaction.Commit(); session.BeginTransaction(); supplierRed = session.Query <Supplier>() .FirstOrDefault(s => (changeValues && s.Id != supplier.Id) || (!changeValues && s.Id == supplier.Id)); session.Refresh(supplierRed); } var curretnClient = addressRed.Client; curretnClient.RedmineNotificationForUnresolved = true; session.Save(curretnClient); if (addressRed.Id != 0) { testAddress = new TestAddress { Id = addressRed.Id }; } if (supplier.Id != 0) { supplier = new TestSupplier { Id = supplierRed.Id }; } if (createIssue) { addressRed.Client.RedmineNotificationForUnresolved = true; session.Save(addressRed.Client); } else { addressRed.Client.RedmineNotificationForUnresolved = false; session.Save(addressRed.Client); } var log = new DocumentReceiveLog(supplierRed, addressRed) { FileName = filename, DocumentType = documentType }; session.Save(log); if (priority) { session.CreateSQLQuery($"INSERT INTO customers.Associations (Name) values('TestUser')") .ExecuteUpdate(); var newAssociationId = session.CreateSQLQuery($"SELECT Id FROM customers.Associations WHERE Name = 'TestUser' LIMIT 1") .UniqueResult <uint>(); session.CreateSQLQuery( $"INSERT INTO customers.PromotionMembers (AssociationId,ClientId) values({newAssociationId},'{curretnClient.Id}')") .ExecuteUpdate(); session.CreateSQLQuery( $"Update usersettings.RetClientsSet SET IsStockEnabled = {(priorityFull ? "1" : "0")} , InvisibleOnFirm = 1 WHERE ClientCode = {curretnClient.Id} ") .ExecuteUpdate(); } session.Flush(); var fi = new FileInfo(log.GetFileName()); var str = fi.DirectoryName; if (!Directory.Exists(str)) { Directory.CreateDirectory(str); } File.Delete(fi.FullName); File.Copy(@"..\..\Data\Waybills\" + log.FileName, fi.FullName); var w = new WaybillService(); var waybill = DocumentReceiveLog.Find(log.Id); w.Process(new EditableList <DocumentReceiveLog> { waybill }); session.Flush(); if (deleteCreatedDirectory && Directory.GetParent(str).Exists) { Directory.GetParent(str).Delete(true); } if (priority) { session.CreateSQLQuery($"DELETE FROM customers.Promoters WHERE Login = '******'").ExecuteUpdate(); } return(log); }
public DocumentForParsing(DocumentReceiveLog log) { DocumentLog = log; FileName = log.GetFileName(); }