Added Error Log code to record errors when import fails

Added Error handling to Import so that Change Manager is turned-on after Import whether it is successful or not.
Don't allow import if the Referenced Objects have not been selected.
Turn On Change Manager if there are no active sessions
Don't crash if the Referenced Objects are not set when you right-click on a Working Draft.
This commit is contained in:
Rich 2017-02-10 16:23:31 +00:00
parent 0deea55d7e
commit 69b7de9fc5
3 changed files with 213 additions and 165 deletions

View File

@ -16,7 +16,10 @@ namespace VEPROMS
{
public partial class dlgExportImport : Form
{
private bool _ConvertROsToTextDuringImport = false;
#region Log4Net
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
private bool _ConvertROsToTextDuringImport = false;
private bool _ConvertROsAndTransitionsToText = false; // set to true when Approval creates an Export file
// B2016-225 notify user when Transitions and/or ROs are converted to text
@ -211,7 +214,7 @@ namespace VEPROMS
if (MyFolder != null) // import a folder - a .expx file
{
TurnChangeManagerOff.Execute();
LoadImportDataDocument();
TryToLoadImportDataDocument();// Added Try Catch Error Handling to assure that the Change Manager is tuned-on
MyDocVersion = null;
isImported = true;
TurnChangeManagerOn.Execute();
@ -226,168 +229,10 @@ namespace VEPROMS
// * set newRODbid to MyDocVersion rodbid
// - or convert ROs to text
TurnChangeManagerOff.Execute();
XmlDocument xd = new XmlDocument();
xd.Load(txtImport.Text);
pbImportProcedure.Maximum = 1;
string rofolderpath = xd.DocumentElement.Attributes.GetNamedItem("rofolderpath").InnerText;
int rodbid = int.Parse(xd.DocumentElement.Attributes.GetNamedItem("rodbid").InnerText);
int rofstid = int.Parse(xd.DocumentElement.Attributes.GetNamedItem("rofstid").InnerText);
if (MyDocVersion.DocVersionAssociationCount > 0)
{
// use current ROPath
MyRODb = RODb.GetJustRoDb(MyDocVersion.DocVersionAssociations[0].MyROFst.MyRODb.RODbID);
// if the current RO Path and the import file RO Path are not the same
// then ask if we should import using the current workingdraft RO Path, convert the ROs to text, or cancel the import
if (MyRODb.FolderPath != rofolderpath)
{
dlgImpHowToHandleROs dlg = new dlgImpHowToHandleROs();
dlg.ImportedROFolder = rofolderpath;
dlg.WorkingDraftROFolder = MyRODb.FolderPath;
dlg.ShowDialog(this);
if (dlg.CancelImport)
{
this.Cursor = Cursors.Default;
this.btnImport.Enabled = true; // allow user to select a different export file to import
this.btnDoImport.Enabled = true; // allow user to change mind and perform the import
return;
}
_ConvertROsToTextDuringImport = dlg.ConvertROsToText;
}
// this saves the old RO database ID and the current RO database ID so that we can change the RODBIDs in the RO links
newRODbID = MyRODb.RODbID;
oldRODbID = rodbid;
}
else
{
#region NeedToSelectROPath
// MyDocVersion does not have an RO database (ro folder path) assigned to it so we need to select an RO Path
List<string> localROPaths = new List<string>();
RODbInfoList rolist = RODbInfoList.Get();
foreach (RODbInfo dbi in rolist)
{
if (dbi.FolderPath == rofolderpath && dbi.RODbID == rodbid)
{
MyRODb = RODb.GetJustRoDb(rodbid);
oldRODbID = newRODbID = rodbid;
break;
}
// B2016-175 have the correct (matching) RO Path but the rodbid is different (procedure came from a different SQL database)
// We can use the RO Path but we need to change the rodbid in the RO links of the procedure we are importing
else if (dbi.FolderPath == rofolderpath && dbi.RODbID != rodbid)
{
MyRODb = RODb.GetByFolderPath(rofolderpath);
newRODbID = MyRODb.RODbID;
oldRODbID = rodbid;
break;
}
else
{
DirectoryInfo di = new DirectoryInfo(dbi.FolderPath);
if (di.Exists)
localROPaths.Add(dbi.FolderPath);
}
}
if (MyRODb == null)
{
if (localROPaths.Count == 0)
{
MessageBox.Show("There has been no RO folder defined for this database.\r\n\r\nIn order to import a procedure, you need to assign a RO folder path.\r\n\r\nImport process will terminate.");
this.Cursor = Cursors.Default;
return;
}
else
{
this.Cursor = Cursors.Default;
dlgPickROFolder dlg = new dlgPickROFolder();
dlg.ImportedROFolder = rofolderpath;
dlg.LocalROFolders = localROPaths;
dlg.ShowDialog(this);
if ((dlg.SelectedROFolder ?? string.Empty) != string.Empty) // B2015-216 If the return value is null treat it like an empty string
{
MyRODb = RODb.GetByFolderPath(dlg.SelectedROFolder);
RODbInfo myRODBInfo = RODbInfo.Get(MyRODb.RODbID);
oldRODbID = newRODbID = MyRODb.RODbID;
ROFstInfo fstInfo = null;
foreach (ROFstInfo tmp in myRODBInfo.RODbROFsts)
if (fstInfo == null || tmp.ROFstID > fstInfo.ROFstID)
fstInfo = tmp;
using (DocVersion dv = MyDocVersion.Get())
{
using (ROFst fst = fstInfo.Get())
{
dv.DocVersionAssociations.Add(fst);
dv.Save();
}
dv.Reset_DocVersionAssociations();
MyDocVersion.RefreshDocVersionAssociations();
}
}
else
{
MessageBox.Show("Since you did not pick an existing RO folder defined for this database, the import process will terminate.");
this.Close();// Close the Import Window
return;
}
}
}
#endregion
} // end - need to select RO Path
// use resolvedProcNum to determine if procedure is 'unique', i.e. if the procedure number exists
// and user does not overwrite or copy, then the procedure should NOT be imported. Fix for B2016-045
bool resolvedProcNum = true;
foreach (ProcedureInfo pi in MyDocVersion.Procedures)
{
// procedure numbers that contain a hyphen may have the hyphen represented as the unicode character
// '\u8209?' or the '-' character. If proc number is same except for hyphen representation, they
// should be considered the same procedure (fix for B2016-084)
string hyphenNum = pi.MyContent.Number == null ? "" : pi.MyContent.Number.Replace(@"\u8209?", "-").Replace("\u2011", "-").Replace(@"\u9586?",@"\").Replace("\u2572", @"\");
string hyphenImpNum = xd.SelectSingleNode("procedure/content/@number").InnerText;
// bug fix C2015-044 - jsj
// - the cancel button would ignor the user's wishes and proceed with the import (overwriting the existing procedure)
// - also found that the message about overwriting or making a copy wasn't appearing because we where not converting the import procedure number
// - our standard unicode dash (\u8209?) before conparing the existing and imported
// - also found the Overrite and make a copy of messages looked too similar - fixed that as well.
//hyphenImpNum = hyphenImpNum == null ? "" : hyphenImpNum.Replace("\u8030?", "-"); -did not find any reason to have this \u8030? - note retested sourcesafe doc for B2016-084 without this logic and it was fine
hyphenImpNum = hyphenImpNum == null ? "" : hyphenImpNum.Replace(@"\u8209?", "-").Replace("\u2011", "-").Replace(@"\u9586?", @"\").Replace("\u2572", @"\");
if (hyphenNum == hyphenImpNum)
{
string msg = string.Format("The procedure you are importing{0}already exists in this procedure set.\n\nDo you want to OVERWRITE the existing procedure?", !hyphenImpNum.Equals("")?string.Format(" ({0}) ",hyphenImpNum):" ");
DialogResult dr = MessageBox.Show(this, msg, "Overwrite Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop);
if (dr == DialogResult.Yes)
{
ImportProcedureOverwrite(xd, pi);
isImported = true;
break;
}
if (dr == DialogResult.No)
{
msg = string.Format("Do you want to import {0} as a COPY of the existing procedure?\n\nThis will prefix the procedure number with \"Copy of\"", !hyphenImpNum.Equals("") ? string.Format("({0})", hyphenImpNum) : "the procedure");
dr = MessageBox.Show(this, msg , "Create Copy Of Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop);
if (dr == DialogResult.Yes)
{
ImportProcedureCopy(xd);
isImported = true;
break;
}
else
resolvedProcNum = false;
}
if (dr == System.Windows.Forms.DialogResult.Cancel)
{
canceledPressed = true;
resolvedProcNum = false;
}
break; // user selected No or Cancel so break out of the foreach loop
}
}
if (!canceledPressed && !isImported && resolvedProcNum)
{
ImportProcedureNew(xd);
isImported = true;
}
// Added Try Catch Error Handling to assure that the Change Manager is tuned-on
bool result = TryToImportProcedure(ref isImported, ref canceledPressed);
TurnChangeManagerOn.Execute();
if (!result) return;
if (isImported)
{
TimeSpan elapsed = DateTime.Now.Subtract(MyStart);
@ -419,6 +264,197 @@ namespace VEPROMS
btnCloseImport.PerformClick();
}
}
private bool TryToImportProcedure(ref bool isImported, ref bool canceledPressed)
{
try
{
return ImportProcedure(ref isImported, ref canceledPressed);
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
_MyLog.Warn("Failed during Procedure Import", ex);
this.Close();
return false;
}
}
private bool ImportProcedure(ref bool isImported, ref bool canceledPressed)
{
XmlDocument xd = new XmlDocument();
xd.Load(txtImport.Text);
pbImportProcedure.Maximum = 1;
string rofolderpath = xd.DocumentElement.Attributes.GetNamedItem("rofolderpath").InnerText;
int rodbid = int.Parse(xd.DocumentElement.Attributes.GetNamedItem("rodbid").InnerText);
int rofstid = int.Parse(xd.DocumentElement.Attributes.GetNamedItem("rofstid").InnerText);
if (MyDocVersion.DocVersionAssociationCount > 0)
{
// use current ROPath
MyRODb = RODb.GetJustRoDb(MyDocVersion.DocVersionAssociations[0].MyROFst.MyRODb.RODbID);
// if the current RO Path and the import file RO Path are not the same
// then ask if we should import using the current workingdraft RO Path, convert the ROs to text, or cancel the import
if (MyRODb.FolderPath != rofolderpath)
{
dlgImpHowToHandleROs dlg = new dlgImpHowToHandleROs();
dlg.ImportedROFolder = rofolderpath;
dlg.WorkingDraftROFolder = MyRODb.FolderPath;
dlg.ShowDialog(this);
if (dlg.CancelImport)
{
this.Cursor = Cursors.Default;
this.btnImport.Enabled = true; // allow user to select a different export file to import
this.btnDoImport.Enabled = true; // allow user to change mind and perform the import
return false; // Return False to Indicate that the Import did not succeed
}
_ConvertROsToTextDuringImport = dlg.ConvertROsToText;
}
// this saves the old RO database ID and the current RO database ID so that we can change the RODBIDs in the RO links
newRODbID = MyRODb.RODbID;
oldRODbID = rodbid;
}
else
{
#region NeedToSelectROPath
// MyDocVersion does not have an RO database (ro folder path) assigned to it so we need to select an RO Path
List<string> localROPaths = new List<string>();
RODbInfoList rolist = RODbInfoList.Get();
foreach (RODbInfo dbi in rolist)
{
if (dbi.FolderPath == rofolderpath && dbi.RODbID == rodbid)
{
MyRODb = RODb.GetJustRoDb(rodbid);
oldRODbID = newRODbID = rodbid;
break;
}
// B2016-175 have the correct (matching) RO Path but the rodbid is different (procedure came from a different SQL database)
// We can use the RO Path but we need to change the rodbid in the RO links of the procedure we are importing
else if (dbi.FolderPath == rofolderpath && dbi.RODbID != rodbid)
{
MyRODb = RODb.GetByFolderPath(rofolderpath);
newRODbID = MyRODb.RODbID;
oldRODbID = rodbid;
break;
}
else
{
DirectoryInfo di = new DirectoryInfo(dbi.FolderPath);
if (di.Exists)
localROPaths.Add(dbi.FolderPath);
}
}
if (MyRODb == null)
{
if (localROPaths.Count == 0)
{
MessageBox.Show("There has been no RO folder defined for this database.\r\n\r\nIn order to import a procedure, you need to assign a RO folder path.\r\n\r\nImport process will terminate.");
this.Cursor = Cursors.Default;
return false;// Return False to Indicate that the Import did not succeed
}
else
{
this.Cursor = Cursors.Default;
dlgPickROFolder dlg = new dlgPickROFolder();
dlg.ImportedROFolder = rofolderpath;
dlg.LocalROFolders = localROPaths;
dlg.ShowDialog(this);
if ((dlg.SelectedROFolder ?? string.Empty) != string.Empty) // B2015-216 If the return value is null treat it like an empty string
{
MyRODb = RODb.GetByFolderPath(dlg.SelectedROFolder);
RODbInfo myRODBInfo = RODbInfo.Get(MyRODb.RODbID);
oldRODbID = newRODbID = MyRODb.RODbID;
ROFstInfo fstInfo = null;
foreach (ROFstInfo tmp in myRODBInfo.RODbROFsts)
if (fstInfo == null || tmp.ROFstID > fstInfo.ROFstID)
fstInfo = tmp;
using (DocVersion dv = MyDocVersion.Get())
{
using (ROFst fst = fstInfo.Get())
{
dv.DocVersionAssociations.Add(fst);
dv.Save();
}
dv.Reset_DocVersionAssociations();
MyDocVersion.RefreshDocVersionAssociations();
}
}
else
{
MessageBox.Show("Since you did not pick an existing RO folder defined for this database, the import process will terminate.");
this.Close();// Close the Import Window
return false;// Return False to Indicate that the Import did not succeed
}
}
}
#endregion
} // end - need to select RO Path
// use resolvedProcNum to determine if procedure is 'unique', i.e. if the procedure number exists
// and user does not overwrite or copy, then the procedure should NOT be imported. Fix for B2016-045
bool resolvedProcNum = true;
foreach (ProcedureInfo pi in MyDocVersion.Procedures)
{
// procedure numbers that contain a hyphen may have the hyphen represented as the unicode character
// '\u8209?' or the '-' character. If proc number is same except for hyphen representation, they
// should be considered the same procedure (fix for B2016-084)
string hyphenNum = pi.MyContent.Number == null ? "" : pi.MyContent.Number.Replace(@"\u8209?", "-").Replace("\u2011", "-").Replace(@"\u9586?", @"\").Replace("\u2572", @"\");
string hyphenImpNum = xd.SelectSingleNode("procedure/content/@number").InnerText;
// bug fix C2015-044 - jsj
// - the cancel button would ignor the user's wishes and proceed with the import (overwriting the existing procedure)
// - also found that the message about overwriting or making a copy wasn't appearing because we where not converting the import procedure number
// - our standard unicode dash (\u8209?) before conparing the existing and imported
// - also found the Overrite and make a copy of messages looked too similar - fixed that as well.
//hyphenImpNum = hyphenImpNum == null ? "" : hyphenImpNum.Replace("\u8030?", "-"); -did not find any reason to have this \u8030? - note retested sourcesafe doc for B2016-084 without this logic and it was fine
hyphenImpNum = hyphenImpNum == null ? "" : hyphenImpNum.Replace(@"\u8209?", "-").Replace("\u2011", "-").Replace(@"\u9586?", @"\").Replace("\u2572", @"\");
if (hyphenNum == hyphenImpNum)
{
string msg = string.Format("The procedure you are importing{0}already exists in this procedure set.\n\nDo you want to OVERWRITE the existing procedure?", !hyphenImpNum.Equals("") ? string.Format(" ({0}) ", hyphenImpNum) : " ");
DialogResult dr = MessageBox.Show(this, msg, "Overwrite Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop);
if (dr == DialogResult.Yes)
{
ImportProcedureOverwrite(xd, pi);
isImported = true;
break;
}
if (dr == DialogResult.No)
{
msg = string.Format("Do you want to import {0} as a COPY of the existing procedure?\n\nThis will prefix the procedure number with \"Copy of\"", !hyphenImpNum.Equals("") ? string.Format("({0})", hyphenImpNum) : "the procedure");
dr = MessageBox.Show(this, msg, "Create Copy Of Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop);
if (dr == DialogResult.Yes)
{
ImportProcedureCopy(xd);
isImported = true;
break;
}
else
resolvedProcNum = false;
}
if (dr == System.Windows.Forms.DialogResult.Cancel)
{
canceledPressed = true;
resolvedProcNum = false;
}
break; // user selected No or Cancel so break out of the foreach loop
}
}
if (!canceledPressed && !isImported && resolvedProcNum)
{
ImportProcedureNew(xd);
isImported = true;
}
return true;// Import Suceeded
}
// Added Error Handling to assure that Change Manager is turned-on regardless of success or failure of the import
private void TryToLoadImportDataDocument()
{
try
{
LoadImportDataDocument();
}
catch (Exception ex)
{
_MyLog.Warn("Failure During Import", ex);
}
}
private void ImportProcedureNew(XmlDocument xd)
{
//add imported procedure

View File

@ -538,6 +538,13 @@ namespace VEPROMS
}
else
{
dvi.RefreshDocVersionAssociations(); // Refresh Associations Count
//Only allow Import if the Referenced Object Database is set
if ( dvi.DocVersionAssociationCount == 0)
{
MessageBox.Show("Prior to Importing Procedures you must set the Referenced Object Database", "No RO Database set", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
int ownerid = MySessionInfo.CheckOutItem(dvi.VersionID, CheckOutType.DocVersion);
dlgExportImport dlg = new dlgExportImport("Import", dvi);
dlg.MyNewProcedure = null;
@ -1494,6 +1501,7 @@ namespace VEPROMS
private void CloseSessionsNoLongerActive()
{
SessionInfoList sil = SessionInfoList.Get();
int i = 0;
foreach(SessionInfo si in sil)
{
if (si.DTSEnd == null && si.MachineName == Environment.MachineName && si.UserID == Volian.Base.Library.VlnSettings.UserID)
@ -1502,12 +1510,16 @@ namespace VEPROMS
{
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(si.ProcessID);
}
catch(Exception ex)// Process not found
catch (Exception ex)// Process not found
{
Session.Delete(si.SessionID);// Remove Session record associated with a closed process
}
}
else if (si.DTSEnd == null)
i = i + 1;
}
if (i == 0)// Turn-on Change Manger if there are no active Sessions
TurnChangeManagerOn.Execute();
}
//public bool IsEnhancedDocumentOpen(ItemInfo ii)
//{

View File

@ -209,7 +209,7 @@ namespace VEPROMS.CSLA.Library
{
get
{
if (DocVersionAssociations == null) return false;
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";