// ======================================================================== // Copyright 2006 - Volian Enterprises, Inc. All rights reserved. // Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE // ------------------------------------------------------------------------ // $Workfile: $ $Revision: $ // $Author: $ $Date: $ // // $History: $ // ======================================================================== using System; using System.Data; using System.Data.SqlClient; using Csla; using Csla.Data; using System.Collections.Generic; using System.IO; using System.Threading; using System.Xml; using System.Text.RegularExpressions; //using VEPROMS.Properties; namespace VEPROMS.CSLA.Library { public partial class DocVersion : IVEDrillDown { public static DocVersion GetFromDB(int versionID) // get data from database (don't look in cache first) { if (!CanGetObject()) throw new System.Security.SecurityException("User not authorized to view a DocVersion"); try { DocVersion tmp = DataPortal.Fetch(new PKCriteria(versionID)); if (tmp.ErrorMessage == "No Record Found") { tmp.Dispose(); // Clean-up DocVersion tmp = null; } return tmp; } catch (Exception ex) { throw new DbCslaException("Error on DocVersion.Get", ex); } } public bool NewerRoFst { get { if (DocVersionAssociations == null || DocVersionAssociations.Count == 0) return false; using (ROFstInfo roFstInfo = ROFstInfo.GetJustROFst(DocVersionAssociations[0].ROFstID)) { using (RODbInfo rdi = RODbInfo.GetJustRODB(roFstInfo.RODbID)) { string rofstPath = rdi.FolderPath + @"\ro.fst"; if (!File.Exists(rofstPath)) return false; FileInfo fiRofst = new FileInfo(rofstPath); // if the database Ro.Fst is newer or if the files have identical DTS, // assume that they are the same file. if (roFstInfo.DTS >= fiRofst.LastWriteTimeUtc) return false; // next see if the data is the same size, i.e. byte count of record and byte count // of file. If different sizes, the date/time stamp check will hold. // B2022-026 RO Memory reduction - new logic var bytes = ROFSTLookup.GetRofstLookupBytes(roFstInfo.ROFstID); if (bytes != null && fiRofst.Length != bytes.Length) return fiRofst.LastWriteTimeUtc > roFstInfo.DTS; // if we can't tell by the DTS or size, compare the contents. Get all of the rodb's // rofsts of the size of the file & compare bytes. return ROFstInfoList.ROFstDiffBySize(rofstPath, rdi.RODbID, (int)fiRofst.Length); } } } } public bool ROfstLastCompleted { get { if (DocVersionAssociations == null || DocVersionAssociationCount == 0) return true; // no ROs associated this will turn off the update ROs button if (LastCompleted(DocVersionAssociations[0]) == string.Empty) return false; return true; } } // return the date/time of the last time the RO Update was done and ran all the way through completion private string LastCompleted(DocVersionAssociation dva) { XmlDocument xd = new XmlDocument(); if (dva.Config == null || dva.Config.Length == 0) return string.Empty; xd.LoadXml(dva.Config); XmlNode xn = xd.DocumentElement.SelectSingleNode("//ROUpdate"); if (xn == null) return string.Empty; XmlAttribute att = xn.Attributes["LastCompleted"]; if (att == null) return string.Empty; return att.InnerText; } // B2017-125 put info in the config as to the status of loading RO Figures during the Update RO Values // This will help us determine if the Update RO Values was terminated during the loading of the RO Figures public bool ROfstLoadingFigures { get { if (DocVersionAssociations == null || DocVersionAssociationCount == 0) return true; // no ROs associated this will turn off the update ROs button if (ROLoadingFigures(DocVersionAssociations[0]) == string.Empty) return false; return true; } } // B2017-125 return the loading figures status private string ROLoadingFigures(DocVersionAssociation dva) { XmlDocument xd = new XmlDocument(); if (dva.Config == null || dva.Config.Length == 0) return string.Empty; xd.LoadXml(dva.Config); XmlNode xn = xd.DocumentElement.SelectSingleNode("//ROUpdate"); if (xn == null) return string.Empty; XmlAttribute att = xn.Attributes["LoadingFigures"]; if (att == null) return string.Empty; return att.InnerText; } #region VersionType public VersionTypeEnum eVersionType { get { return (VersionTypeEnum)_VersionType; } set { _VersionType = (int)value; } } #endregion #region DocVersion Config [NonSerialized] private DocVersionConfig _DocVersionConfig; public DocVersionConfig DocVersionConfig { get { if (_DocVersionConfig == null) { _DocVersionConfig = new DocVersionConfig(this); _DocVersionConfig.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_DocVersionConfig_PropertyChanged); } return _DocVersionConfig; } } private void _DocVersionConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { Config = _DocVersionConfig.ToString(); } #endregion #region UserSettings /// /// These settings are set on the user interface side. /// This is used to control whether the Name and/or Title is displayed /// next to the tree nodes in the user interface /// private bool _DisplayTreeNodeNames = true; public bool DisplayTreeNodeNames { get { return _DisplayTreeNodeNames; } set { _DisplayTreeNodeNames = value; } } private bool _DisplayTreeNodeTitles = false; public bool DisplayTreeNodeTitles { get { return _DisplayTreeNodeTitles; } set { _DisplayTreeNodeTitles = value; } } #endregion public override string ToString() { // assume that at least one of the two options was selected string rtnstr = ""; if (_DisplayTreeNodeNames) rtnstr = Name; if (_DisplayTreeNodeTitles) { if (rtnstr.Length > 0) rtnstr += " - "; rtnstr += Title; } return rtnstr; //return string.Format("{0} - {1}", Name, Title); } #region IVEDrillDown //public System.Collections.IList GetChildren() //{ // return null; //} //public bool HasChildren //{ // get { return _ItemID > 0; } //} //public IVEDrillDown ActiveParent //{ // get // { // return MyFolder; // } //} //private Format _ActiveFormat = null; //public Format ActiveFormat //{ // get // { // if (_ActiveFormat == null) // _ActiveFormat = LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat; // return _ActiveFormat; // } // set // { // _ActiveFormat = null; // } //} //public Format LocalFormat //{ // get { return MyFormat; } //} public ConfigDynamicTypeDescriptor MyConfig { get { return DocVersionConfig; } } #endregion public DocVersionInfo MyDocVersionInfo { get { return DocVersionInfo.Get(VersionID); } } } public partial class DocVersionInfo : IVEDrillDownReadOnly { public TimeSpan tsTimeOut = TimeSpan.FromSeconds(6); public bool pathExists(string path) { bool exists = true; Thread t = new Thread( new ThreadStart(delegate() { exists = System.IO.File.Exists(path); }) ); t.Start(); bool completed = t.Join(tsTimeOut); //wait 6 seconds then 3 then 1.5 then .75 seconds if (!completed) { exists = false; t.Abort(); if (tsTimeOut > TimeSpan.FromSeconds(1)) tsTimeOut = TimeSpan.FromTicks(tsTimeOut.Ticks / 2); } return exists; } // The following dictionary is used to store the state of the ro.fst check so that it is // not made repeatedly in NewerRoFst. (B2017-050) private static Dictionary NewerRoFstLookup = new Dictionary(); private static bool AddToRoFstLookup(string key, bool result) { if (!NewerRoFstLookup.ContainsKey(key)) NewerRoFstLookup.Add(key, result); return result; } public bool NewerRoFst { get { if (DocVersionAssociations == null || DocVersionAssociationCount==0) return false; ROFstInfo roFstInfo = ROFstInfo.GetJustROFst(DocVersionAssociations[0].ROFstID); RODbInfo rdi = RODbInfo.GetJustRODB(roFstInfo.RODbID); string rofstPath = rdi.FolderPath + @"\ro.fst"; //if (!File.Exists(rofstPath)) return false; if (!pathExists(rofstPath)) { _MyLog.WarnFormat("RO Path '{0}' could not be found", rofstPath); return false; } FileInfo fiRofst = new FileInfo(rofstPath); // if the database Ro.Fst is newer or if the files have identical DTS, // assume that they are the same file. // put this in a dictionary so we don't have to keep testing to see if the file version of ro.fst is newer than database version string key = string.Format("{0}-{1}", DocVersionAssociations[0].ROFstID, fiRofst.LastWriteTimeUtc); if (NewerRoFstLookup.ContainsKey(key)) return NewerRoFstLookup[key]; if (roFstInfo.DTS >= fiRofst.LastWriteTimeUtc) return AddToRoFstLookup(key, false); TimeSpan ts = roFstInfo.DTS - fiRofst.LastWriteTimeUtc; if (ts.TotalSeconds > -1F) return AddToRoFstLookup(key, false); // next see if the data is the same size, i.e. byte count of record and byte count // of file. If different sizes, the date/time stamp check will hold. // B2022-026 RO Memory reduction - new logic var bytes = ROFSTLookup.GetRofstLookupBytes(roFstInfo.ROFstID); if (bytes != null && fiRofst.Length != bytes.Length) return AddToRoFstLookup(key, fiRofst.LastWriteTimeUtc > roFstInfo.DTS); // if we can't tell by the DTS or size, compare the contents. Get all of the rodb's // rofsts of the size of the file & compare bytes. return AddToRoFstLookup(key, ROFstInfoList.ROFstDiffBySize(rofstPath, rdi.RODbID, (int)fiRofst.Length)); } } public bool ROfstLastCompleted { get { if (DocVersionAssociations == null || DocVersionAssociationCount == 0) return true; // no ROs associated this will turn off the update ROs button if (LastCompleted(DocVersionAssociations[0]) == string.Empty) return false; // the AssociatinoConfig does not have completed date for update ROs - this will turn on the update ROs button return true; } } // return the date/time of the last time the RO Update was done and ran all the way through completion private string LastCompleted(AssociationInfo associationInfo) { AssociationConfig ac = new AssociationConfig(associationInfo); return ac.ROUpdate_LastCompleted; } // B2017-125 return the loading figures status private string ROLoadingFigures(AssociationInfo associationInfo) { AssociationConfig ac = new AssociationConfig(associationInfo); return ac.ROUpdate_LoadingFigures; } #region Enhanced // B2022-148: cannot insert outside transition in a background document that references a related EOP – transition is converted to text // Check if the 2 doc versions are linked, i.e. one is source and the other is enhanced linked to the source public static bool Linked(DocVersionInfo dv1, DocVersionInfo dv2) { DocVersionConfig dvc1 = dv1.DocVersionConfig; DocVersionConfig dvc2 = dv2.DocVersionConfig; bool isLinked1 = dvc1 != null && (dvc1.MyEnhancedDocuments != null && dvc1.MyEnhancedDocuments.Count > 0); bool isLinked2 = dvc2 != null && (dvc2.MyEnhancedDocuments != null && dvc2.MyEnhancedDocuments.Count > 0); bool relatedEnh = false; if (isLinked1 && isLinked2) { // does source point to this docversion as enhanced, and does this enhanced point to this source: bool isSource1 = dvc1.MyEnhancedDocuments.Count == 1 && dvc1.MyEnhancedDocuments[0].Type == 0 && dvc1.MyEnhancedDocuments[0].VersionID == dv2.VersionID; bool isSource2 = dvc2.MyEnhancedDocuments.Count == 1 && dvc2.MyEnhancedDocuments[0].Type == 0 && dvc2.MyEnhancedDocuments[0].VersionID == dv1.VersionID; if (isSource1 || isSource2) { int sourceVersionID = isSource1 ? dv1.VersionID : dv2.VersionID; DVEnhancedDocuments enhList = isSource1 ? dvc2.MyEnhancedDocuments : dvc1.MyEnhancedDocuments; if (enhList != null) { foreach (DVEnhancedDocument ded in enhList) { if (ded.Type != 0 && ded.VersionID == sourceVersionID) // found it. { relatedEnh = true; break; } } } } } return relatedEnh; } #endregion #region SearchPaths public string _SearchDVPath; public string SearchDVPath { get { if (_SearchDVPath == null) _SearchDVPath = ActiveParent.SearchDVPath + "\u0007" + Name; return _SearchDVPath; } } public string SearchPath { get { return ""; } } // B2021-076: Proms search results are not presented in order when printed to PDF public string SearchDefaultSort { get { return string.Empty; } } #endregion #region UnlinkEnhancedDocVersion // Unlink (clear) enhanced from source for this docversion. Refresh all related cache items. public void DoUnlinkEnhancedDocVersion() { try { // get source docversion id for refresh - used later (check for null, just in case): int sdvid = DocVersionConfig != null && DocVersionConfig.MyEnhancedDocuments.Count > 0 ? DocVersionConfig.MyEnhancedDocuments[0].VersionID : -1; using (ContentInfoList cil = ContentInfoList.DoEnhancedDocVersionUnlink(this.VersionID)) { foreach (ContentInfo ci in cil) { using (Content c = ci.Get()) { // first refresh configs because the ContentInfo.Refresh causes events to occur that refresh screen // and if configs aren't done first, the screen refresh, if based on config data, will not be correct. foreach (ItemInfo ii in ci.ContentItems) ii.RefreshConfig(); ContentInfo.Refresh(c); } } } // Refresh this docversioninfo. Note that this and below refresh use a docversion retrieved from the // database, i.e. 'GetFromDB'. This was necessary since this dialog is working with docversion writable // objects. DocVersionInfo.Refresh(DocVersion.GetFromDB(this.VersionID)); // Refresh the source document's docversioninfo if (sdvid > -1) { using (DocVersion dv = DocVersion.GetFromDB(sdvid)) { DocVersionInfo.Refresh(dv); } } } catch (Exception ex) { throw new DbCslaException("Error on DocVersionInfo:DoUnlinkEnhancedDocVersion", ex); } } #endregion UnlinkEnhanced #region DocVersion Config [NonSerialized] private DocVersionConfig _DocVersionConfig; public DocVersionConfig DocVersionConfig { get { return (_DocVersionConfig != null ? _DocVersionConfig : _DocVersionConfig = new DocVersionConfig(this)); } } private void DocVersionConfigRefresh() { _DocVersionConfig = null; } #endregion #region MOVE TO DOCVERSION CONFIG private string GetProfile(string grp, string nam) { return GetProfile(grp, nam, false); } private string GetProfile(string grp, string nam, bool flag) { DocVersionConfig dvcfg = DocVersionConfig; string buff = null; if (grp != null && !grp.Equals(string.Empty)) { buff = dvcfg.GetValue(grp, nam); // get the value of 'nam' in 'grp' if (buff == null || buff.Equals(string.Empty)) { if (!flag) buff = string.Format("<{0}-{1}>", grp, nam); else buff = null; } } return buff; } // B2021-066: Procedure PC/PC resolve procedure number with Unit Specific info public string UnitSpecific(string str, int len, ItemInfo ii) { ProcedureInfo pi = ii as ProcedureInfo; if (pi == null) // B2022-004: Don't crash if Proc PC/PC (ii is from a list, so wasn't an ItemInfo) { pi = ProcedureInfo.Get(ii.ItemID); } if (pi == null) return ""; // B2023-035 for save the current select child (selectedSlave) and use the child number // that was selected when printed. This is needed for when "Other" applicability // values are referenced. For BNPP Alarms, sometimes the SelectedSlave value was set // to the corresponding "Other" value, but we needed to use the selected child that was // selected from the print button/menu in order to get the correct "Other" value. int docVerSelectedSlave = DocVersionConfig.SelectedSlave; int procInfoSelectedChildToPrint = pi.SelectedChildToPrint; if (procInfoSelectedChildToPrint != 0) { DocVersionConfig.SelectedSlave = procInfoSelectedChildToPrint; } string unitdes = "ID"; string prefix = null; string fromunitdes = null; str = ItemInfo.ConvertToDisplayText(pi.MyContent.Number); bool hastoken = false; // Determine if there is a token in the procedure number data, default is ID if (str.ToUpper().Contains(@" -1) { try { int sindx = str.ToUpper().IndexOf(@"", sindx + 1); unitdes = str.Substring(sindx + 3, eindx - (sindx + 3)); unitdes = unitdes.ToUpper(); } catch { unitdes = "ID"; } } } if (unitdes == "NUMBER") fromunitdes = DocVersionConfig.Unit_Number; else if (unitdes == "ID") fromunitdes = DocVersionConfig.Unit_ID; else if (unitdes == "NAME") fromunitdes = DocVersionConfig.Unit_Name; else if (unitdes == "TEXT") fromunitdes = DocVersionConfig.Unit_Text; // B2021-145: For applicability, the tree view & pdf file name are not getting resolved when using any of the ‘OTHER’ tokens // B2022-023 also check for other followed by a space else if (unitdes == "OTHERTEXT" || unitdes == "OTHER TEXT") fromunitdes = DocVersionConfig.Other_Unit_Text; else if (unitdes == "OTHERNUMBER" || unitdes == "OTHER NUMBER") fromunitdes = DocVersionConfig.Other_Unit_Number; else if (unitdes == "OTHERNAME" || unitdes == "OTHER NAME") fromunitdes = DocVersionConfig.Other_Unit_Name; else if (unitdes == "OTHERID" || unitdes == "OTHER ID") fromunitdes = DocVersionConfig.Other_Unit_ID; else fromunitdes = DocVersionConfig.Unit_ID; DocVersionConfig.SelectedSlave = docVerSelectedSlave; //B2023-035 reset the selected Slave // adjustments to the procedure number for applicability can be defined in 2 places: // 1) mstr below: working draft properties/Applicability/Procedure number field for each unit can have text. The '#' in this // field represents the procdure number & any text prefixing it, will be used to prefix the procedure number // 2) fromunitdes above: this is defined on the procedure number, seen on procedure properties, and is a token with // optional '-xxx' after the U, see above for possible tokens. string mstr = (MyConfig as DocVersionConfig).Unit_ProcedureNumber; string[] units = mstr.Split(",".ToCharArray()); string[] fromdata = fromunitdes.Split(",".ToCharArray()); // SelectedSlave is > 0 if a unit has been selected, for example from print or approve. It represents that index into the list of units. // F2023-098: depending on where this is called from & how data is set, the DocVersionConfig.SelectedSlave may be 0, but the // procInfoSelectedChildToPrint will always have the correct value, i.e. 0 if not printing & the selected slave from the print selection. // Check for procInfoSelectedChildToPrint > 0 also: if (DocVersionConfig.SelectedSlave > 0 || procInfoSelectedChildToPrint > 0) { prefix = units[0].Replace("#", ""); if (str.ToUpper().IndexOf(@" -1) return prefix + Regex.Replace(str, @"\<[uU]-[a-zA-Z]+\>", fromunitdes); return prefix + Regex.Replace(str, @"\<[uU]\>", fromunitdes); } // The following code is used to handle the treeview/tree node representation of the procedure number with any appropriate // unit specifications resolved, as follows: // 1) [] (square brackets) are placed around any prefixes determined from the token or the Procedure Number data on // the working draft properties. If None, i.e. no units, are applicable, as selected from the Step Properties/Applicability tab. // there will be no text between the brackets to represent no applicability // 2) , (commas) are used as a delimiter. Only have 1 comma separating the prefix, there may be no text if some units are // not applicable, but code exists here so that ',,,' does not appear in the treenode // 3) don't duplicate resolved text, for example if NUMBER is used, and prefix text would be '[A,A,B,C,C]', only show '[A,B,C]' bool sometext = false; // flag to use since don't want ',,,,,' before number List prefs = new List(); for (int i = 1; i <= UnitNames.Length; i++) { bool procAppl = pi.ApplInclude(i); string tokRepAndPrefix = units[i - 1].Replace("#", "") + (hastoken ? fromdata[i - 1] : ""); if (tokRepAndPrefix != "") { sometext = true; if (prefs.Count > 0 && prefs.Contains(tokRepAndPrefix)) tokRepAndPrefix = ""; else if (procAppl) prefs.Add(tokRepAndPrefix); } if (procAppl && tokRepAndPrefix != "") prefix = prefix + (prefix == null ? tokRepAndPrefix : (prefix != null && prefix.Length > 0 && prefix[prefix.Length - 1] != ',' ? "," : "") + tokRepAndPrefix); } str = Regex.Replace(str, @"\<[uU]-[a-zA-Z]+\>", ""); str = Regex.Replace(str, @"\<[uU]\>", ""); return (!sometext) ? str: "[" + prefix + "]" + str; } public string UnitSpecific(string str, int len) { // This routine retrieves the procedure number format from the // current directory and uses it to adjust the procedure number // in the specified string string retvalu = ""; string asis = "#"; if (str == null || str.Equals(string.Empty)) return retvalu; // return a null (empty) string /* * Bug fix: B2005-017 3/2/2005 * Need to use the largest procedure number length that's in the * SET.DFF file. "LargestNumber" is the largest length after the * procedure number is replaced via the SET.INI file "replace" list. * if(len==0)len=LargestNumber; */ // TODO: Do we need this line?-->>> if(len==0)len=LargestRawSetNumber; //GetPrivateProfileString("unit", "procedure number", asis, mstr, MAXPATH, "proc.ini"); string pnum = asis; //rhm/jcb stuff 20120511 //string mstr = GetProfile("Unit", "ProcedureNumber", true); string mstr = DocVersionConfig.Unit_ProcedureNumber; if (mstr != null && !mstr.Equals(string.Empty)) pnum = mstr; if (pnum.Equals(asis)) retvalu = str; else if (pnum[0] == '!') { mstr = GetProfile("Replace", mstr, true); // true allow it to return a null if not found if (mstr == null) retvalu = str; // no replacement, use procedure number as is } else { retvalu = ""; string[] pnumsplit = pnum.Split(new Char[] { '#' }); int cnt = 0; foreach (string s in pnumsplit) { if (!s.Equals(string.Empty)) { if ((cnt == 0) && (str.StartsWith(" "))) { string padding = new string(' ', s.Length); retvalu += padding; } else retvalu += s; } else retvalu += str.Trim(); cnt++; } // append trailing blanks or procedure number (str) if (str.EndsWith(" ")) { // count number of trailing blanks and append them to retvalu cnt = str.Length - 1; while (cnt > 0 && str[cnt] == ' ') cnt--; retvalu += new string(' ', str.Length - cnt - 1); } } return retvalu; } public string Evaluate(string str, int len) { string retval = null; string swhir = "PSU"; /* order in which to check */ string pn; if (str.Length > 1 && str[1] == '-') { int swptr = swhir.IndexOf((str.ToUpper())[0]); string sav = str.Substring(len); str = str.Substring(0, len); string substr = str.Substring(2); substr = substr.Replace(" ", ""); while (swptr >= 0 && swptr < swhir.Length && retval == null) { switch (swhir[swptr]) { case 'U': //retval = GetProfile("Unit", substr, true); if (substr.ToLower() == "id") retval = this.DocVersionConfig.Unit_ID; if (substr.ToLower() == "name") retval = this.DocVersionConfig.Unit_Name; if (substr.ToLower() == "number") retval = this.DocVersionConfig.Unit_Number; if (substr.ToLower() == "text") retval = this.DocVersionConfig.Unit_Text; break; case 'S': //retval = GetProfile("Procedure_Set", substr, true); if (substr.ToLower() == "id") retval = this.DocVersionConfig.Unit_ProcedureSetID; if (substr.ToLower() == "name") retval = this.DocVersionConfig.Unit_ProcedureSetName; break; case 'P': //TODO: THIS IS A GLOBAL IN THE 16 BIT CODE!!!! string procnumber = ""; pn = UnitSpecific(procnumber, 0); retval = GetProfile(pn, substr, true); break; } if (retval == null) // .Equals(string.Empty)) swptr++; } str += sav; } else if (len == 1 && (str.ToUpper())[0] == 'U') { retval = this.DocVersionConfig.Unit_Number; } else if (len == 2 && str.StartsWith("ID")) { retval = this.DocVersionConfig.Unit_ID; } if (retval == null) retval = string.Format("<{0}>", str.Substring(0, len)); return retval; } public string ProcessDocVersionSpecificInfo(string rawvalue) { string str = rawvalue; string rtnstr = string.Empty; int l = rawvalue.Length; while (l > 0) { int ptr = str.IndexOf('<'); int cptr = (ptr == -1) ? -1 : str.IndexOf('>'); // jsj 2/5/10 added "|| (ptr > cptr)" to fix bug where rawvalue = "Insert token for ->Step<- to transition back to." if (ptr == -1 || (ptr > -1 && ((cptr == -1) || (ptr > cptr)))) { rtnstr += str; l = 0; // jump out of while loop } else { int cnt = ptr; if (cnt > 0) { rtnstr += str.Substring(0, cnt); l -= cnt; str = str.Substring(ptr); } ptr = str.IndexOf('>') + 1; cnt = ptr; rtnstr += Evaluate(str.Substring(1, cnt - 2), cnt - 2); l -= cnt; str = str.Substring(ptr); } } return rtnstr; } #endregion ItemInfoList _Procedures = null; public ItemInfoList Procedures { get { return (_Procedures != null ? _Procedures : _Procedures = ItemInfoList.GetList(_ItemID, (int)E_FromType.Procedure)); } } public void ResetProcedures() { _Procedures = null; } public static void ResetProcedures(int versionID) { string key = versionID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (DocVersionInfo dvi in _CacheByPrimaryKey[key]) dvi.ResetProcedures(); } #region IVEReadOnlyItem public System.Collections.IList GetChildren() { return Procedures; } //public bool ChildrenAreLoaded //{ // get { return _iil == null; } //} public bool HasChildren { get { return _ItemID > 0; } } public IVEDrillDownReadOnly ActiveParent { get { return MyFolder; } } public FormatInfo ActiveFormat { get { return LocalFormat != null ? LocalFormat : ActiveParent.ActiveFormat; } } public FormatInfo LocalFormat { get { //Console.WriteLine("DV Local {0} {1} {2}", (MyFormat == null) ? "MYformat is null" : MyFormat.Name,FormatID,(MyFormat == null)?0:MyFormat.FormatID); return MyFormat; } } public ConfigDynamicTypeDescriptor MyConfig { get { return DocVersionConfig; } } //public bool HasStandardSteps() //{ return false; } #region PasteChild public ItemInfo PasteChild(int copyStartID) // pastes into an 'empty' docversion { ItemInfo cpItem = ItemInfo.Get(copyStartID); try { DocVersionInfo dvi = DataPortal.Fetch(new VersionPastingPartCriteria(VersionID, copyStartID, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); ItemInfo tmp = dvi.Procedures[0] as ItemInfo; if (tmp != null) { tmp.UpdateTransitionText(); tmp.UpdatePastedStepTransitionText(); } return tmp; } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Details were written to the Error Log.", "Paste Failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return null; } } #endregion #region UserSettings /// /// These settings are set on the user interface side. /// This is used to control whether the Name and/or Title is displayed /// next to the tree nodes in the user interface /// private bool _DisplayTreeNodeNames = true; public bool DisplayTreeNodeNames { get { return _DisplayTreeNodeNames; } set { _DisplayTreeNodeNames = value; } } private bool _DisplayTreeNodeTitles = false; public bool DisplayTreeNodeTitles { get { return _DisplayTreeNodeTitles; } set { _DisplayTreeNodeTitles = value; } } #endregion public override string ToString() { // assume that at least one of the two options was selected string rtnstr = ""; if (_DisplayTreeNodeNames) rtnstr = Name; if (_DisplayTreeNodeTitles) { if (rtnstr.Length > 0) rtnstr += " - "; rtnstr += Title; } return rtnstr; //return string.Format("{0} - {1}", Name, Title); } //public string ToString(string str,System.IFormatProvider ifp) //{ // return ToString(); //} public ItemInfo LastChild() { return MyItem.LastSibling; } public ItemInfo FirstChild() { return MyItem; } #endregion #region DataPortal private void DataPortal_Fetch(VersionPastingPartCriteria criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] DocVersionInfo.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.Parameters.AddWithValue("@VersionID", criteria.VersionID); cm.Parameters.AddWithValue("@StartItemID", criteria.StartItemID); cm.Parameters.AddWithValue("@DTS", criteria.DTS); //ABC cm.Parameters.AddWithValue("@UserID", criteria.UserID); //ABC SqlParameter param_ContentID = new SqlParameter("@ThisVersionID", SqlDbType.Int); param_ContentID.Direction = ParameterDirection.Output; cm.Parameters.Add(param_ContentID); cm.CommandText = "PasteDocVersionChild"; cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); } } // removing of item only needed for local data portal if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client) ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { if (!ex.Message.Contains("This working draft has been deleted") && !ex.Message.Contains("This current step has been deleted in another session")) { if (_MyLog.IsErrorEnabled) _MyLog.Error("DocVersion.DataPortal_Fetch", ex); } _ErrorMessage = ex.Message; throw new DbCslaException("DocVersion.DataPortal_Fetch", ex); } } #endregion #region Extension partial class DocVersionInfoExtension : extensionBase { public override void Refresh(DocVersionInfo tmp) { tmp.DocVersionConfigRefresh(); } } #endregion public ROFstInfo GetROFst(int rodbid) { if (DocVersionAssociations == null || DocVersionAssociations.Count == 0) // No RO Association for this Data { if (FirstBadRODBIDProblemDetected) _MyLog.ErrorFormat("<<>> - Missing RO Association\r\nMissing RO Association for this Folder ([{0}] - {1})", VersionID, MyFolder.Name); return null; } foreach (AssociationInfo dva in DocVersionAssociations) { if (dva.MyROFst.RODbID == rodbid) return dva.MyROFst; } if (DocVersionAssociations.Count == 1) // Different Association and ROUsage values for RODBID - default to asssociation value { if (FirstBadRODBIDProblemDetected) _MyLog.ErrorFormat("<<>> - ROUsage Does Not match Association\r\nROUsage (RODBID = {0}) does not match Association Information (RODBID = {1}) for this Folder ([2] - {3})", rodbid, DocVersionAssociations[0].MyROFst.RODbID, VersionID, MyFolder.Name); return DocVersionAssociations[0].MyROFst; } // More than one association record - Cannot guess which to return if (FirstBadRODBIDProblemDetected) _MyLog.ErrorFormat("<<>> - More than One Association Record\r\nROUsage (RODBID = {0}) does not match any of the {1} Associations for this Folder ([{2}] -{3})", rodbid, DocVersionAssociations.Count, VersionID, MyFolder.Name); return null; } private static List _HasBadRODBIDProblem = new List(); private bool FirstBadRODBIDProblemDetected { get { if (_HasBadRODBIDProblem.Contains(VersionID)) return false; _HasBadRODBIDProblem.Add(VersionID); return true; } } public bool IsFolder { get { return false; } } public bool IsDocVersion { get { return true; } } public bool IsProcedure { get { return false; } } public bool IsSection { get { return false; } } public bool IsStep { get { return false; } } public int MultiUnitCount { get { return DocVersionConfig.Unit_Count; } } private string[] _UnitNames; public string[] UnitNames { get { if (_UnitNames == null) { _UnitNames = DocVersionConfig.Unit_Name.Split(','); _UnitNames = new string[DocVersionConfig.Unit_Count]; int j = 0; for (int k = 1; k <= DocVersionConfig.MaxSlaveIndex; k++) { DocVersionConfig.SelectedSlave = k; try { _UnitNames[j] = DocVersionConfig.Unit_Name; j++; } catch { } } DocVersionConfig.SelectedSlave = 0; } return _UnitNames; } } #region Proc Set Specific info support public static string GetInheritedSIValue(ProcedureInfo pi, string fieldName) { string val = null; DocVersionConfig dvConfig = new DocVersionConfig(pi.MyDocVersion.Config); if (dvConfig != null) { val = dvConfig.GetValue("SI", fieldName); if (val != null && val != "") return val; // the value exists within the docversion level } FolderInfo fi = pi.MyDocVersion.MyFolder; while (fi != null) { FolderConfig folderConfig = new FolderConfig(fi.Config); if (folderConfig != null) { val = folderConfig.GetValue("SI", fieldName); if (val != null && val != "") return val; // the value exists within this folder } fi = fi.ActiveParent as FolderInfo; } return val; } #endregion } #region VersionPastingPartCriteria [Serializable()] public class VersionPastingPartCriteria { #region Properties private int _VersionID; public int VersionID { get { return _VersionID; } set { _VersionID = value; } } private int _StartItemID; public int StartItemID { get { return _StartItemID; } set { _StartItemID = value; } } private DateTime _DTS; public DateTime DTS { get { return _DTS; } set { _DTS = value; } } private string _UserID; public string UserID { get { return _UserID; } set { _UserID = value; } } #endregion #region Constructor public VersionPastingPartCriteria(int versionID, int startItemID, DateTime dts, string userID) { _VersionID = versionID; _StartItemID = startItemID; _DTS = dts; _UserID = userID; } #endregion } #endregion public enum VersionTypeEnum : int { WorkingDraft = 0, Temporary = 1, Revision = 128, Approved = 129 } public partial class DocVersionInfoList { public static DocVersionInfoList GetNonEnhancedDocVersions() { try { DocVersionInfoList tmp = DataPortal.Fetch(new DocVersionNonEnhancedListCriteria()); DocVersionInfo.AddList(tmp); tmp.AddEvents(); return tmp; } catch (Exception ex) { throw new DbCslaException("Error on DocVersionInfoList.GetNonEnhancedDocVersions", ex); } } [Serializable()] protected class DocVersionNonEnhancedListCriteria { public DocVersionNonEnhancedListCriteria() { ;} } private void DataPortal_Fetch(DocVersionNonEnhancedListCriteria criteria) { this.RaiseListChangedEvents = false; try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "vesp_GetNonEnhancedDocVersions"; cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { IsReadOnly = false; while (dr.Read()) { DocVersionInfo dvInfo = new DocVersionInfo(dr); this.Add(dvInfo); } IsReadOnly = true; } } } } catch (Exception ex) { Database.LogException("DocVersionInfoList.DataPortal_Fetch", ex); throw new DbCslaException("DocVersionInfoList.DataPortal_Fetch", ex); } this.RaiseListChangedEvents = true; } } }