public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail, string specCertType) { SpecCertGenerationResult result; switch (specCertType) { case "edi": result = new EdiSpecCertGenerator().GenerateSpecCert(mapDetail); break; case "xml": result = new XmlSpecCertGenerator().GenerateSpecCert(mapDetail); break; case "flatfile": result = new FlatFileSpecCertGenerator().GenerateSpecCert(mapDetail); break; default: throw new NotSupportedException(string.Format("Spec cert type {0} is not supported", specCertType)); break; } return(result); }
public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); string specCertName = string.Format("{0} - Spec Cert - XML - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); Dictionary <string, XmlLinkInfo> xmlLinks = new Dictionary <string, XmlLinkInfo>(); IReferenceableElement refElement; string rootNodeName = null; foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } refElement = useSource ? link.Source : link.Target; //Skip first part of path string path = refElement.Name.Substring(refElement.Name.IndexOf("->") + 2); if (refElement.ReferenceType == ReferenceType.Document && !xmlLinks.ContainsKey(path)) { if (rootNodeName == null) { rootNodeName = refElement.Name.Substring(0, refElement.Name.IndexOf("->")); specCertWorksheet.Cells[RootNodeNameRowIndex, RootNodeNameColumnIndex].Value = rootNodeName; } xmlLinks.Add(path, new XmlLinkInfo(link.Name)); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // TODO: Check done for receive only // Set IsOptional to false if formula is not of type Logical* if (useSource) { foreach (XmlLinkInfo xmlLink in xmlLinks.Values) { ITransformLink link = links[xmlLink.LinkName]; if (link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; if (formula.FormulaType == FormulaType.LogicalString || formula.FormulaType == FormulaType.LogicalExistence) { xmlLink.IsOptional = true; } } } } result.PathsUsed = new List <string>(); int row = StartRowIndex; int mandatoryColumnIndex = useSource ? ReceiveMandatoryColumnIndex : SendMandatoryColumnIndex; string[] prevParts = null; List <string> paths = xmlLinks.Keys.ToList(); paths.Sort(); foreach (string path in paths) { XmlLinkInfo xmlLink = xmlLinks[path]; string[] parts = path.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length > 5) { throw new NotSupportedException(string.Format("More than 5 levels deep xml elements are not supported. Path: {0}", path)); } int level = 0; if (prevParts != null) { while (level < prevParts.Length && level < parts.Length && prevParts[level] == parts[level]) { level++; } } prevParts = parts; while (level < parts.Length) { bool highlightRow = level < parts.Length - 1 || xmlLinks.Count(entry => entry.Key.StartsWith(path + "->")) != 0; AddRow(specCertWorksheet, row, level + 1, parts[level], mandatoryColumnIndex, highlightRow, xmlLink.IsOptional || level < parts.Length - 1); level++; row++; } result.PathsUsed.Add(path); } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }
public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); if (!mappingsAvailable) { // Not thread safe, but we don't really need it right now ReadCovastToX12Maps(); } string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); //string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase); string specCertName = string.Format("{0} - Spec Cert - 4010 - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); Dictionary <string, List <string> > covastToX12Map; string templateFile = string.Empty; switch (mapDetail.DocumentType) { case 810: templateFile = TemplateFile_810; if (useSource) { covastToX12Map = Map_810_Inbound; } else { covastToX12Map = Map_810_Outbound; } break; case 850: templateFile = TemplateFile_850; if (useSource) { covastToX12Map = Map_850_Inbound; } else { covastToX12Map = Map_850_Outbound; } break; case 856: templateFile = TemplateFile_856; if (useSource) { covastToX12Map = Map_856_Inbound; } else { covastToX12Map = Map_856_Outbound; } break; default: result.Errors.Add(string.Format("Spec cert generation for document type {0} not supported", mapDetail.DocumentType)); return(result); } templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, templateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } //using (StreamReader streamReader = new StreamReader(templateFile)) //using (ExcelPackage pck = new ExcelPackage(streamReader.BaseStream)) using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); // Check if version is supported // Take any link and check source/target name IList <ITransformLink> refLinks = mapDetail.Map.Facets[0].Links; IReferenceableElement refElement = null; for (int i = 0; i < refLinks.Count; i++) { if (useSource) { refElement = mapDetail.Map.Facets[0].Links[i].Source; } else { refElement = mapDetail.Map.Facets[0].Links[i].Target; } if (refElement.ReferenceType == ReferenceType.Document) { break; } } if (refElement.Name.StartsWith("ASC_X12_810_004_010_DEFAULT_X") == false && refElement.Name.StartsWith("ASC_X12_850_004_010_DEFAULT_X") == false && refElement.Name.StartsWith("ASC_X12_856_004_010_DEFAULT_X") == false) { throw new NotSupportedException(string.Format("Invalid root (version) name {0}. Valid value is ASC_X12_810|850|856_004_010_DEFAULT_X", refElement.Name.Substring(0, refElement.Name.IndexOf("->")))); } foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // Get all enum values // Enum values are determined as // Document(1) => One or more Formula (Equal) => Logical Or formula => Document(2) // allEnumValues store first Document(1), Document(2), enum values Dictionary <string, Dictionary <string, List <string> > > allEnumValues = new Dictionary <string, Dictionary <string, List <string> > >(); foreach (ITransformLink link in links.Values) { if (useSource == false) { if (link.Source.ReferenceType == ReferenceType.Document && link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; // In case of enum formulas it's possible that scripting formula is first applied to convert enum value // If that is the case ignore scripting formula and move to next formula if (formula.Parameters != null && formula.FormulaType == FormulaType.Scripting) { ITransformLink equalLink = fromLinks[formula.Name]; if (equalLink.Target != null && equalLink.Target.ReferenceType == ReferenceType.Formula) { string equalFormulaName = equalLink.Target.Name; formula = formulas[equalFormulaName]; } } if (formula.Parameters != null && formula.FormulaType == FormulaType.Equality) { // Assumption: only 1 enum value and only 1 target formula exist string enumValue = null; foreach (IParameter parameter in formula.Parameters) { if (parameter.Reference.ReferenceType == ReferenceType.Literal) { if (enumValue != null) { throw new NotSupportedException("Multiple enum values in 1 formula"); } enumValue = parameter.Reference.Name; } } // If there are enum values check what's the target of these values if (!string.IsNullOrEmpty(enumValue)) { ITransformLink equalLink = fromLinks[formula.Name]; if (equalLink.Target != null && equalLink.Target.ReferenceType == ReferenceType.Formula) { string targetFormulaName = equalLink.Target.Name; IFormula targetFormula = formulas[targetFormulaName]; // Check if the equal link points to logical or formula, if it is then the target link of that will give us the document if (targetFormula.FormulaType == FormulaType.LogicalOr) { string targetDocumentName = null; ITransformLink logicalOrLink = fromLinks[targetFormulaName]; if (logicalOrLink.Target != null && logicalOrLink.Target.ReferenceType == ReferenceType.Document) { targetDocumentName = logicalOrLink.Target.Name; if (!string.IsNullOrEmpty(targetDocumentName)) { Dictionary <string, List <string> > nodeEnumValues; if (!allEnumValues.TryGetValue(link.Source.Name, out nodeEnumValues)) { nodeEnumValues = new Dictionary <string, List <string> >(); allEnumValues.Add(link.Source.Name, nodeEnumValues); } List <string> enumValues = null; if (!nodeEnumValues.TryGetValue(targetDocumentName, out enumValues)) { enumValues = new List <string>(); nodeEnumValues.Add(targetDocumentName, enumValues); } enumValues.Add(enumValue); } } } } } } } } } foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { IReferenceableElement toRefElement = link.Target; IReferenceableElement fromRefElement = link.Source; if (useSource) { toRefElement = link.Source; fromRefElement = link.Target; } if (toRefElement.ReferenceType == ReferenceType.Document) { try { x12Paths = null; // Check if source has enum values List <string> enumValues = GetEnumValues(link.Source.Name, toRefElement, allEnumValues); if (enumValues != null) { AddEnumValues(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, enumValues); } else { if (fromRefElement.ReferenceType == ReferenceType.Formula && (formulas[fromRefElement.Name].FormulaType == FormulaType.LogicalExistence || formulas[fromRefElement.Name].FormulaType == FormulaType.LogicalString || formulas[fromRefElement.Name].FormulaType == FormulaType.GreaterThan)) { AddExistsCheckNote(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource); //SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "n"); } else { // In case of looping do not set the mandatory flag for the segment if (!(fromRefElement.ReferenceType == ReferenceType.Formula && formulas[fromRefElement.Name].FormulaType == FormulaType.Looping)) { SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "y"); } //else //SetMandatoryValue(specCertWorksheet, covastToX12Map, toRefElement.Name, useSource, "n"); } } if (x12Paths != null) { result.PathsUsed.AddRange(x12Paths); } } catch (Exception ex) { result.Errors.Add(ex.Message); } } } } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }
private const string DefaultSegmentDelimiter = "13 10"; // \r\n public SpecCertGenerationResult GenerateSpecCert(MapDetail mapDetail) { SpecCertGenerationResult result = new SpecCertGenerationResult(); string currentDir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(SpecCertGenerator)).Location); string specCertName = string.Format("{0} - Spec Cert - Flat File - {1} - {2}.xlsx", mapDetail.OrgName, mapDetail.DocumentType, mapDetail.Direction.ToLower()); string specCertPath = Path.Combine(currentDir, specCertName); bool useSource = string.Equals(mapDetail.Direction, "receive", StringComparison.OrdinalIgnoreCase); string templateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplateFile); if (File.Exists(specCertPath)) { File.Delete(specCertPath); } using (ExcelPackage pck = new ExcelPackage(new FileInfo(templateFile))) { ExcelWorkbook workBook = pck.Workbook; ExcelWorksheet specCertWorksheet = workBook.Worksheets[1]; specCertWorksheet.Name = string.Format("{0} {1} Spec Worksheet", mapDetail.DocumentType, mapDetail.Direction.ToUpper()); Dictionary <string, ITransformLink> links = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> fromLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, ITransformLink> toLinks = new Dictionary <string, ITransformLink>(); Dictionary <string, IFormula> formulas = new Dictionary <string, IFormula>(); Dictionary <string, LinkInfo> xmlLinks = new Dictionary <string, LinkInfo>(); IReferenceableElement refElement; string rootNodeName = null; specCertWorksheet.Cells[ElementDelimiterRowIndex, ElementDelimiterColumnIndex].Value = DefaultElementDelimiter; specCertWorksheet.Cells[SegmentDelimiterRowIndex, SegmentDelimiterColumnIndex].Value = DefaultSegmentDelimiter; foreach (ITransformGroup transformGroup in mapDetail.Map.Facets) { foreach (ITransformLink link in transformGroup.Links) { links.Add(link.Name, link); if (link.Source != null && link.Source.ReferenceType == ReferenceType.Formula && !fromLinks.ContainsKey(link.Source.Name)) { fromLinks.Add(link.Source.Name, link); } if (link.Target != null && link.Target.ReferenceType == ReferenceType.Formula && !toLinks.ContainsKey(link.Target.Name)) { toLinks.Add(link.Target.Name, link); } refElement = useSource ? link.Source : link.Target; if (refElement.Name.Contains("->") == false) { continue; } //Skip first part of path string path = refElement.Name.Substring(refElement.Name.IndexOf("->") + 2); if (refElement.ReferenceType == ReferenceType.Document && !xmlLinks.ContainsKey(path)) { xmlLinks.Add(path, new LinkInfo(link.Name)); } } foreach (IFormula formula in transformGroup.Formulas) { formulas.Add(formula.Name, formula); } } // TODO: Check done for receive only // Set IsOptional to false if formula is not of type Logical* if (useSource) { foreach (LinkInfo xmlLink in xmlLinks.Values) { ITransformLink link = links[xmlLink.LinkName]; if (link.Target.ReferenceType == ReferenceType.Formula) { IFormula formula = formulas[link.Target.Name]; if (formula.FormulaType == FormulaType.LogicalString || formula.FormulaType == FormulaType.LogicalExistence) { xmlLink.IsOptional = true; } } } } result.PathsUsed = new List <string>(); int row = StartRowIndex; int mandatoryColumnIndex = useSource ? ReceiveMandatoryColumnIndex : SendMandatoryColumnIndex; List <string> paths = xmlLinks.Keys.ToList(); paths.Sort(); string lastIterationSegmentName = null; foreach (string path in paths) { LinkInfo link = xmlLinks[path]; string[] partsTemp = path.Split(new string[] { "->" }, StringSplitOptions.RemoveEmptyEntries); List <string> parts = partsTemp.ToList(); parts.Remove("Loop"); // Only loop name is ignored as loop name is added on the segment row if (parts.Count <= 1) { continue; } if (parts.Count > 3) { throw new NotSupportedException(string.Format("More than 5 levels deep xml elements are not supported. Path: {0}", path)); } string loopName = parts[0].Contains("Loop") ? parts[0] : string.Empty; // Loop name is optional string segmentName = string.IsNullOrEmpty(loopName) ? parts[0] : parts[1]; // Some maps may have mapping only for segments (e.g. Header, BodyLoop etc.) that means // data element is optional string dataElementName = null; int index = 2; if (string.IsNullOrEmpty(loopName)) { index = 1; } if (parts.Count > index) { dataElementName = parts[index]; } // If segment changed then add segment row if (segmentName.Equals(lastIterationSegmentName, StringComparison.OrdinalIgnoreCase) == false) { AddSegmentRow(specCertWorksheet, row, loopName, segmentName, mandatoryColumnIndex, link.IsOptional || !string.IsNullOrEmpty(dataElementName)); lastIterationSegmentName = segmentName; row++; } if (string.IsNullOrEmpty(dataElementName) == false) { AddDataElementRow(specCertWorksheet, row, dataElementName, mandatoryColumnIndex, link.IsOptional); row++; } result.PathsUsed.Add(path); } // Add errors to spec cert worksheet //AddErrorsWorksheet(workBook, result); if (result.PathsUsed.Count != 0) { pck.SaveAs(new FileInfo(specCertPath)); result.SpecCertGenerated = true; } } result.SpecCertPath = specCertPath; return(result); }