diff --git a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs index bfdfa46d..3283357c 100644 --- a/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs +++ b/PROMS/VEPROMS.CSLA.Library/Extension/ItemExt.cs @@ -11,6 +11,7 @@ using System.Xml; using System.Drawing; using System.Text.RegularExpressions; using Volian.Base.Library; +using System.Linq; namespace VEPROMS.CSLA.Library { @@ -402,6 +403,99 @@ namespace VEPROMS.CSLA.Library return tmpForLink; } + //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. + // This will be used to simulate the non-high level part of a tab + // for case where sorting and all other fields match + // Note: This is cut down to improve the sort's performance + // but congruent to Volian.Print.Library.PDFReport-> BuildStepTab(ItemInfo item) + public string BuildStepTab() + { + StringBuilder sret = new StringBuilder(); + ItemInfo pitem = this; + + while (!pitem.IsSection && !pitem.IsHigh) + { + using (StepInfo stpinfo = StepInfo.Get(pitem.ItemID)) + { + string thisTab = stpinfo.MyTab.CleanText; + + string typeName = stpinfo.FormatStepData.StepEditData.TypeMenu.MenuItem; + + if (!string.IsNullOrEmpty(thisTab)) + { + thisTab = thisTab.Trim(); + } + + // if the tab is null or + // if the the tab is not a letter or number OR + // the tab is an AND or OR type and is the letter "o" + // then reset the tab an empty string so that the type name along with the count of that type + // (ex. "AND 2", "OR 3") + if (string.IsNullOrEmpty(thisTab) || (thisTab != string.Empty && (!(char.IsLetterOrDigit(thisTab[0])) || ((pitem.IsAnd || pitem.IsOr || pitem.IsCaution || pitem.IsNote) && thisTab.Contains("o"))))) + { + thisTab = string.Empty; + } + + if (pitem.IsRNOPart) + { + if (string.IsNullOrEmpty(thisTab)) + { + sret.Insert(0, "RNO."); + } + else + { + thisTab = thisTab.Trim(); + + if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) + { + thisTab += "."; + } + + sret.Insert(0, "RNO." + thisTab); + } + } + else if (pitem.IsCaution || pitem.IsNote) + { + // add the Caution or Note count to the tab (ex "Caution 1", "Note 2") + if (string.IsNullOrEmpty(thisTab)) + { + sret.Append("{" + typeName + " " + pitem.Ordinal.ToString() + "}"); + } + else + { + thisTab = thisTab.Trim(" ".ToCharArray()); + sret.Append(thisTab + " " + pitem.Ordinal.ToString() + sret); + } + } + else + { + if (!string.IsNullOrEmpty(thisTab)) + { + thisTab = thisTab.Trim(" ".ToCharArray()); + + if (!thisTab.EndsWith(".") && !thisTab.EndsWith(")")) + { + thisTab += "."; + } + } + else + { + thisTab = "{" + typeName + " " + pitem.Ordinal.ToString() + "}."; + } + + sret.Insert(0, thisTab); + } + } + + pitem = pitem.ActiveParent as ItemInfo; + + if (pitem == null) + break; + } + + return sret.ToString().Trim(" .)".ToCharArray()); + } + public void SetHeader(VE_Font myFont, string myText) { _MyHeader = new MetaTag(myFont); @@ -3134,6 +3228,24 @@ namespace VEPROMS.CSLA.Library //get { return ConvertToDisplayText(MyContent.Number); } } + //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. + //Get Numeric part of HLS Tab + //Used for Certain sorting situations + //If no numeric part then use 999 (will be at end of that level of the sort if there are other items with numbered HLS) + public int NumericSortNumber + { + get + { + string numericpart = null; + if (MyHLS != null) + numericpart = new string(MyHLS?.MyTab?.CleanTextNoSymbols.TakeWhile(Char.IsDigit).ToArray()); + if (!string.IsNullOrEmpty(numericpart) && numericpart.All(char.IsNumber)) + return int.Parse(numericpart); + else + return 999; + } + } + // for step designators (a redefined caution type used in Comanche Peak with the SameRowAsParentMultiLines format flag) // we what to allow for a hard return to allow for multiple designator lines - jsj 5/21/2015 public static string ConvertToMulitLineStepDesignatorDisplayText(string txt) @@ -6139,6 +6251,168 @@ namespace VEPROMS.CSLA.Library throw new DbCslaException("Error on ItemInfoList.GetChildren", ex); } } + + //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. + // Found various inconsistencies in the reports so adding this to manually sort + //instead of binding the sort to 1 or 2 individual fields + public List SortedList(bool sortbyFoundRoid = false) + { + List tmp = new List(this); + if (sortbyFoundRoid) + { + // Priority of Sorting order: + // 1. FoundRoid (by Referenced Object ID) + // 2. SearchDVPath_clean (Which Procedure Set it is in - I.E. EOPs, Background, SAMGs, etc...) + // 3. Keep in order of the Procedures within the set + // 4. Keep in the order of the Section within the Procedure + // 5. NumericSortNumber - numeric part of the HLS if there is one + // 6. Substep Tab - will sort as a string since combined numbers/text + tmp.Sort(comparison: delegate (ItemInfo x, ItemInfo y) + { + int cmp = 0; + int FoundROID_cmp = x.FoundROID.CompareTo(y.FoundROID); + switch (FoundROID_cmp) + { + case int result when result < 0: + cmp -= 10000000; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 10000000; + break; + default: + break; + } + + int DVPath_cmp = x.SearchDVPath_clean.CompareTo(y.SearchDVPath_clean); + switch (DVPath_cmp) + { + case int result when result < 0: + cmp -= 1000000; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 1000000; + break; + default: + break; + } + + if (x.MyProcedure != null && y.MyProcedure != null) + { + cmp += (x.MyProcedure.Ordinal.CompareTo(y.MyProcedure.Ordinal) * 100000); + } + + if (x.ActiveSection != null && y.ActiveSection != null) + { + cmp += (x.ActiveSection.Ordinal.CompareTo(y.ActiveSection.Ordinal) * 100000); + } + + cmp += x.NumericSortNumber.CompareTo(y.NumericSortNumber) * 10; + + if (cmp == 0) + { + int StepTab_cmp = (x.BuildStepTab()).CompareTo(y.BuildStepTab()); + switch (StepTab_cmp) + { + case int result when result < 0: + cmp -= 1; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 1; + break; + default: + break; + } + } + + return cmp; + }); + } + else + { + // Priority of Sorting order: + // 1. SearchDVPath_clean (Which Procedure Set it is in - I.E. EOPs, Background, SAMGs, etc...) + // 2. Keep in order of the Procedures within the set + // 3. Keep in the order of the Section within the Procedure + // 4. NumericSortNumber - numeric part of the HLS if there is one + // 5. Substep Tab - will sort as a string since combined numbers/text + // 6. FoundRoid (by Referenced Object ID) + tmp.Sort(comparison: delegate (ItemInfo x, ItemInfo y) + { + int cmp = 0; + + int DVPath_cmp = x.SearchDVPath_clean.CompareTo(y.SearchDVPath_clean); + switch (DVPath_cmp) + { + case int result when result < 0: + cmp -= 10000000; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 10000000; + break; + default: + break; + } + + if (x.MyProcedure != null && y.MyProcedure != null) + { + cmp += (x.MyProcedure.Ordinal.CompareTo(y.MyProcedure.Ordinal) * 1000000); + } + + if (x.ActiveSection != null && y.ActiveSection != null) + { + cmp += (x.ActiveSection.Ordinal.CompareTo(y.ActiveSection.Ordinal) * 100000); + } + + cmp += (x.NumericSortNumber.CompareTo(y.NumericSortNumber) * 100); + + if (cmp == 0) + { + int StepTab_cmp = (x.BuildStepTab()).CompareTo(y.BuildStepTab()); + switch (StepTab_cmp) + { + case int result when result < 0: + cmp -= 10; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 10; + break; + default: + break; + } + } + + int FoundROID_cmp = x.FoundROID.CompareTo(y.FoundROID); + switch (FoundROID_cmp) + { + case int result when result < 0: + cmp -= 1; + break; + case int result when result == 0: + break; + case int result when result > 0: + cmp += 1; + break; + default: + break; + } + + return cmp; + }); + } + + return tmp; + } + [Serializable()] private class MoveItemCriteria { @@ -7314,11 +7588,11 @@ namespace VEPROMS.CSLA.Library } this.RaiseListChangedEvents = true; } - #endregion - } - #endregion - #region new class TransitionLookup - public delegate ProcedureInfo TransitionLookupEvent(object sender, TransitionLookupEventArgs args); + #endregion + } + #endregion + #region new class TransitionLookup + public delegate ProcedureInfo TransitionLookupEvent(object sender, TransitionLookupEventArgs args); public class TransitionLookupEventArgs { private int _ProcID; diff --git a/PROMS/Volian.Controls.Library/DisplayReports.cs b/PROMS/Volian.Controls.Library/DisplayReports.cs index c0d9b015..a32a2d43 100644 --- a/PROMS/Volian.Controls.Library/DisplayReports.cs +++ b/PROMS/Volian.Controls.Library/DisplayReports.cs @@ -805,16 +805,8 @@ namespace Volian.Controls.Library string SearchString = GetListOfROs(true);// Include the RODbID in the RO list ItemInfoList SearchResults = ItemInfoList.GetListFromROReport(DocVersionList, "", SearchString, ""); - if (!usageSortedByProcedure) // sort on ROs - { - Csla.SortedBindingList sortedResults = new Csla.SortedBindingList(SearchResults); - sortedResults.ApplySort("FoundROID", ListSortDirection.Ascending); - OnPrintRequest(new DisplayReportsEventArgs("Referenced Objects Usage By RO", "RO Usage", sortedResults, usageSortedByProcedure, cbxIncldMissingROs.Checked, paperSize)); - } - else - { - OnPrintRequest(new DisplayReportsEventArgs("Referenced Objects Usage By Procedure", "RO Usage", SearchResults, usageSortedByProcedure, cbxIncldMissingROs.Checked, paperSize)); - } + List sortedResults = SearchResults.SortedList(!usageSortedByProcedure); + OnPrintRequest(new DisplayReportsEventArgs("Referenced Objects Usage By RO", "RO Usage", sortedResults, usageSortedByProcedure, cbxIncldMissingROs.Checked, paperSize)); } else if (cbxTransFromProcs.Checked) { diff --git a/PROMS/Volian.Print.Library/PDFReport.cs b/PROMS/Volian.Print.Library/PDFReport.cs index 05772373..39bf29f8 100644 --- a/PROMS/Volian.Print.Library/PDFReport.cs +++ b/PROMS/Volian.Print.Library/PDFReport.cs @@ -1074,7 +1074,9 @@ namespace Volian.Print.Library string lastProcNum = string.Empty; string lastSection = string.Empty; - string lastDVPath = string.Empty; + //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. + //setting this to something other than empty - otherwise will not print first initial header + string lastDVPath = "start"; if (_ResultList.Count > 0) { foreach (ItemInfo item in _ResultList) @@ -1088,6 +1090,12 @@ namespace Volian.Print.Library // procedure set title at the top of the report (once). if (lastDVPath != "" && lastDVPath != item.SearchDVPath) { + //CSM B2021-043 Step numbering is out of order in RO usage report if RO values exist on steps 10 or higher. + //was placing last item from the precious section in the new section + //place it before starting the new section and then clear items + PutROusageForProcedure(datatable, roUse, headerwidths); + roUse.Clear(); + subTable = new PdfPTable(headerwidths); AddMainPathGroup(datatable, item.SearchDVPath, splitAt, f2, Color.LIGHT_GRAY, 0); lastProcNum = string.Empty; @@ -1138,7 +1146,7 @@ namespace Volian.Print.Library document.Add(datatable); } - private void AddProcROUse(ItemInfo item, SortedDictionary> procRoUse) + private void AddProcROUse(ItemInfo item, Dictionary> procRoUse) { string dictKey = GetCurProcNum(item.SearchPath) + " " + GetCurSectionNumTitle(item); @@ -1157,7 +1165,7 @@ namespace Volian.Print.Library } } - private void PutStepListForProcedure(PdfPTable rotable, SortedDictionary sortedStepList) + private void PutStepListForProcedure(PdfPTable rotable, Dictionary sortedStepList) { // C2017-036 get best available proportional font for symbols that looks close to Arial // Note that Microsoft no longer supplies Arial Unicode MS as of Word16 @@ -1173,13 +1181,13 @@ namespace Volian.Print.Library sortedStepList.Clear(); } - private void PutROusageForROID(PdfPTable curTable, SortedDictionary> procRoUse, float[] headerwidths, int splitAt, bool moreThanOneProcSet) + private void PutROusageForROID(PdfPTable curTable, Dictionary> procRoUse, float[] headerwidths, int splitAt, bool moreThanOneProcSet) { // C2017-036 get best available proportional font for symbols that looks close to Arial // Note that Microsoft no longer supplies Arial Unicode MS as of Word16 iTextSharp.text.Font f2 = pdf.GetFont(Volian.Base.Library.vlnFont.ReportsFont, 10, 0, Color.BLACK); - SortedDictionary sortedStepList = new SortedDictionary(); + Dictionary sortedStepList = new Dictionary(); string lastProcKey = string.Empty; string lastProcNumTitle = string.Empty; string lastDVPath = string.Empty; @@ -1293,7 +1301,7 @@ namespace Volian.Print.Library private void BuildROUsageTableByRO(iTextSharp.text.Document document) { - SortedDictionary> procRoUse = new SortedDictionary>(); + Dictionary> procRoUse = new Dictionary>(); float[] headerwidths = { 20, 80 }; PdfPTable datatable = new PdfPTable(1);