Files
SourceCode/PROMS/VEPROMS.CSLA.Library/Extension/DocVersionExt.cs

1089 lines
35 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ========================================================================
// 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<DocVersion>(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;
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;
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.
if (fiRofst.Length != roFstInfo.ROLookup.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
/// <summary>
/// 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
/// </summary>
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<string, bool> NewerRoFstLookup = new Dictionary<string, bool>();
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.
if (fiRofst.Length != roFstInfo.ROLookup.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 SearchPaths
public string _SearchDVPath;
public string SearchDVPath
{
get
{
if (_SearchDVPath == null)
_SearchDVPath = ActiveParent.SearchDVPath + "\u0007" + Name;
return _SearchDVPath;
}
}
public string SearchPath { get { return ""; } }
#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 "";
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(@"<U"))
{
hastoken = true;
if (str.ToUpper().IndexOf(@"<U-") > -1)
{
try
{
int sindx = str.ToUpper().IndexOf(@"<U-");
int eindx = str.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;
// 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 <U> 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.
if (DocVersionConfig.SelectedSlave > 0)
{
prefix = units[0].Replace("#", "");
if (str.ToUpper().IndexOf(@"<U-") > -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 <U> 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 delimeter. 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<string> prefs = new List<string>();
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] == '!')
{
// look for mstr in SET.INI
// GetPrivateProfileString("replace", mstr, mstr, tonum, 24, "set.ini");
// TODO: NOT SURE IF SET.INI AND PROC.INI HAVE UNIQUE GROUP NAMES!!!!!!!
//mstr = GetProfile("Replace", mstr);
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 inwhich to check */
string pn;
if (str.Length > 1 && str[1] == '-')
{
int swptr = swhir.IndexOf((str.ToUpper())[0]);
//char swchar = '';
//if (swptr != -1)
// swchar = swhir[swptr];
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) //retval.Equals(string.Empty))
{
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;
//retval = this.DocVersionConfig.Other_Unit_ID;
//retval = this.DocVersionConfig.Other_Unit_Name;
//retval = this.DocVersionConfig.Other_Unit_Number;
//retval = this.DocVersionConfig.Other_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 the return value is empty, then the resulting
// evaluation should repeat the token string including
// the braces. - the beginning brace is not passed in.
//if (retval.Equals(string.Empty))
//{
// retval = (char*)mallocq(len + 3);
// strncpy(retval, str - 1, len + 2);
//}
if (retval == null)
retval = string.Format("<{0}>", str.Substring(0, len));
return retval;
}
public string ProcessDocVersionSpecificInfo(string rawvalue)
{
string str = rawvalue;
string rtnstr = "";
int l = rawvalue.Length;
while (l > 0)
{
int ptr = str.IndexOf('<'); //nextDelimiter("<", str, l);
int cptr = (ptr == -1) ? -1 : str.IndexOf('>'); //nextDelimiter(">", ptr, strlen(ptr));
// 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))))
{
//add(new seText(str, l));
//str += l;
rtnstr += str;
l = 0; // jump out of while loop
}
else
{
int cnt = ptr;
if (cnt > 0)
{
//add(new seText(str, cnt));
rtnstr += str.Substring(0, cnt);
l -= cnt;
str = str.Substring(ptr);
}
ptr = str.IndexOf('>') + 1; //nextDelimiter(">", str, l) + 1;
cnt = ptr; //(int)(ptr - str);
//add(new seUser(str + 1, cnt - 2));
rtnstr += Evaluate(str.Substring(1, cnt - 2), cnt - 2);
l -= cnt;
str = str.Substring(ptr); //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<DocVersionInfo>(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
/// <summary>
/// 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
/// </summary>
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("<<<ERROR>>> - 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("<<<ERROR>>> - 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("<<<ERROR>>> - 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<int> _HasBadRODBIDProblem = new List<int>();
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<DocVersionInfoList>(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;
}
}
}