C2020-038: When deleting a procedure, add a prompt so that user has to enter a reason that is saved to database
This commit is contained in:
parent
1f559a0d12
commit
b172dc3080
@ -259,6 +259,23 @@ namespace VEPROMS.CSLA.Library
|
||||
return s;
|
||||
}
|
||||
#endregion
|
||||
#region DelProcReason
|
||||
[Category("General")]
|
||||
[DisplayName("DelProcReason")]
|
||||
[RefreshProperties(RefreshProperties.All)]
|
||||
[Description("Delete Procedure Reason")]
|
||||
public string General_DelProcReason // C2020-038: reason was added when procedure was deleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Xp["General", "DelProcReason"];
|
||||
}
|
||||
set
|
||||
{
|
||||
_Xp["General", "DelProcReason"] = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region FormatCategory
|
||||
//[TypeConverter(typeof(EnumDescConverter))]
|
||||
//public enum FormatColumns : int
|
||||
|
@ -1634,6 +1634,7 @@ namespace VEPROMS.CSLA.Library
|
||||
// remove the enhanced document link information - fixes delete/restore issue of linked steps.
|
||||
// B2017-070 - when retoring a step that once had enhanced links, remove the link info for the notes and cautions as well
|
||||
tmp.RemoveEnhancedFromConfig();
|
||||
Item.ClearDelProcReason(tmp); // C2020-038: reason was added when procedure was deleted, clear on restore
|
||||
return tmp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -2362,6 +2362,7 @@ namespace VEPROMS.CSLA.Library
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ClearDelProcReason(item); // C2020-038: reason was added when procedure was deleted, but delete failed so remove it
|
||||
System.Data.SqlClient.SqlException exSQL = SqlException(ex);
|
||||
if (exSQL != null && exSQL.Message.Contains("###Cannot Delete Item###"))
|
||||
throw exSQL;
|
||||
@ -2370,6 +2371,19 @@ namespace VEPROMS.CSLA.Library
|
||||
}
|
||||
//_MyTimer.ShowElapsedTimes("DeleteItemAndChildren");
|
||||
}
|
||||
// C2020-038: reason was added when procedure was deleted, provide a way to remove it if delete failed
|
||||
public static void ClearDelProcReason(ItemInfo ii)
|
||||
{
|
||||
if (!ii.IsProcedure) return;
|
||||
ProcedureConfig prc = ii.MyConfig as ProcedureConfig;
|
||||
prc.General_DelProcReason = string.Empty;
|
||||
using (Item itm = Item.Get(ii.ItemID))
|
||||
{
|
||||
itm.MyContent.Config = prc.ToString();
|
||||
itm.UserID = Volian.Base.Library.VlnSettings.UserID;
|
||||
itm.Save();
|
||||
}
|
||||
}
|
||||
private static System.Data.SqlClient.SqlException SqlException(Exception ex)
|
||||
{
|
||||
Type sqlExType = typeof(System.Data.SqlClient.SqlException);
|
||||
|
@ -504,7 +504,27 @@ namespace Volian.Controls.Library
|
||||
#region new style
|
||||
if (deletedItems == null)
|
||||
deletedItems = tvAudits.Nodes.Add("Deleted Items");
|
||||
TreeNode tnn = deletedItems.Nodes.Add(iai.ToString());
|
||||
string strR = null;
|
||||
// see if a deleted procedure, from itemaudit, get contentaudit
|
||||
ContentAuditInfoList lDelC = ContentAuditInfoList.GetByDeleteStatus(iai.DeleteStatus);
|
||||
foreach (ContentAuditInfo delC in lDelC)
|
||||
{
|
||||
if (delC.Type >= 0 && delC.Type < 1000)
|
||||
{
|
||||
int indx = delC.Config.IndexOf("DelProcReason");
|
||||
if (indx >= 0 && delC.Config.Length > indx+15) // 15 accounts for 'DelProcReason = "'
|
||||
{
|
||||
string reason = delC.Config.Substring(indx + 15);
|
||||
if (reason != null && reason.Length > 0)
|
||||
{
|
||||
indx = reason.IndexOf("\"");
|
||||
if (indx > 0) strR = reason.Substring(0, reason.IndexOf("\""));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
TreeNode tnn = deletedItems.Nodes.Add(iai.ToString()+"; Reason: " + strR);
|
||||
tnn.Tag = iai;
|
||||
#endregion
|
||||
}
|
||||
|
39
PROMS/Volian.Controls.Library/dlgDelProcReason.cs
Normal file
39
PROMS/Volian.Controls.Library/dlgDelProcReason.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Volian.Controls.Library
|
||||
{
|
||||
// C2020-038: request reason for delete procedure so this can be saved in database
|
||||
// (a few users said that procedures 'disappeared' but this could not be reproduced)
|
||||
public partial class dlgDelProcReason : Form
|
||||
{
|
||||
vlnTreeView VTreeView;
|
||||
public dlgDelProcReason(vlnTreeView tv)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Text = "Verify Delete By " + Volian.Base.Library.VlnSettings.UserID;
|
||||
VTreeView = tv;
|
||||
tbDelProcReason.Focus();
|
||||
}
|
||||
|
||||
private void btnOk_Click(object sender, EventArgs e)
|
||||
{
|
||||
VTreeView.DelProcReason = tbDelProcReason.Text;
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
VTreeView.DelProcReason = null;
|
||||
}
|
||||
|
||||
private void tbDelProcReason_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
btnYes.Enabled = (tbDelProcReason.Text != null && tbDelProcReason.Text.Length > 0) ;
|
||||
}
|
||||
}
|
||||
}
|
115
PROMS/Volian.Controls.Library/dlgDelProcReason.designer.cs
generated
Normal file
115
PROMS/Volian.Controls.Library/dlgDelProcReason.designer.cs
generated
Normal file
@ -0,0 +1,115 @@
|
||||
namespace Volian.Controls.Library
|
||||
{
|
||||
partial class dlgDelProcReason
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.tbDelProcReason = new System.Windows.Forms.TextBox();
|
||||
this.btnYes = new System.Windows.Forms.Button();
|
||||
this.btnNo = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(23, 15);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(379, 34);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "Are you sure you want to delete this procedure?\r\n A reason must be entered befor" +
|
||||
"e the delete can be done.";
|
||||
//
|
||||
// tbDelProcAnnot
|
||||
//
|
||||
this.tbDelProcReason.Location = new System.Drawing.Point(33, 58);
|
||||
this.tbDelProcReason.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
|
||||
this.tbDelProcReason.Name = "tbDelProcAnnot";
|
||||
this.tbDelProcReason.Size = new System.Drawing.Size(319, 22);
|
||||
this.tbDelProcReason.TabIndex = 1;
|
||||
this.tbDelProcReason.TextChanged += new System.EventHandler(this.tbDelProcReason_TextChanged);
|
||||
//
|
||||
// btnYes
|
||||
//
|
||||
this.btnYes.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btnYes.Enabled = false;
|
||||
this.btnYes.Location = new System.Drawing.Point(191, 88);
|
||||
this.btnYes.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
|
||||
this.btnYes.Name = "btnYes";
|
||||
this.btnYes.Size = new System.Drawing.Size(61, 30);
|
||||
this.btnYes.TabIndex = 2;
|
||||
this.btnYes.Text = "Yes";
|
||||
this.btnYes.UseVisualStyleBackColor = true;
|
||||
this.btnYes.Click += new System.EventHandler(this.btnOk_Click);
|
||||
//
|
||||
// btnNo
|
||||
//
|
||||
this.btnNo.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnNo.Location = new System.Drawing.Point(287, 88);
|
||||
this.btnNo.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
|
||||
this.btnNo.Name = "btnNo";
|
||||
this.btnNo.Size = new System.Drawing.Size(65, 30);
|
||||
this.btnNo.TabIndex = 3;
|
||||
this.btnNo.Text = "No";
|
||||
this.btnNo.UseVisualStyleBackColor = true;
|
||||
this.btnNo.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// dlgDelProcAnnot
|
||||
//
|
||||
this.AcceptButton = this.btnYes;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnNo;
|
||||
this.ClientSize = new System.Drawing.Size(405, 129);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.btnNo);
|
||||
this.Controls.Add(this.btnYes);
|
||||
this.Controls.Add(this.tbDelProcReason);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2);
|
||||
this.MaximizeBox = false;
|
||||
this.MaximumSize = new System.Drawing.Size(423, 176);
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(423, 176);
|
||||
this.Name = "dlgDelProcAnnot";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Verify Delete";
|
||||
this.TopMost = true;
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox tbDelProcReason;
|
||||
private System.Windows.Forms.Button btnYes;
|
||||
private System.Windows.Forms.Button btnNo;
|
||||
}
|
||||
}
|
120
PROMS/Volian.Controls.Library/dlgDelProcReason.resx
Normal file
120
PROMS/Volian.Controls.Library/dlgDelProcReason.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
@ -391,6 +391,12 @@ namespace Volian.Controls.Library
|
||||
get { return _MyUserInfo; }
|
||||
set { _MyUserInfo = value; }
|
||||
}
|
||||
private string _DelProcReason; // C2020-038: request reason for delete procedure so this can be saved in database
|
||||
public string DelProcReason
|
||||
{
|
||||
get { return _DelProcReason; }
|
||||
set { _DelProcReason = value; }
|
||||
}
|
||||
#region Local Vars
|
||||
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
@ -3046,9 +3052,13 @@ namespace Volian.Controls.Library
|
||||
typeDescription = "Folder"; //C2020-026 specific description of what user is trying to delete
|
||||
}
|
||||
//C2020-026 added standardized wording when attempting to delete
|
||||
DialogResult result = FlexibleMessageBox.Show("Are you sure you want to delete this " + typeDescription + "?", "Verify Delete",
|
||||
DialogResult result = DialogResult.No;
|
||||
if (_LastProcedureInfo == null)
|
||||
{
|
||||
result = FlexibleMessageBox.Show("Are you sure you want to delete this " + typeDescription + "?", "Verify Delete",
|
||||
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||
if (result == DialogResult.Yes)
|
||||
}
|
||||
if (_LastProcedureInfo != null || result == DialogResult.Yes)
|
||||
{
|
||||
if (_LastFolderInfo != null)
|
||||
{
|
||||
@ -3090,27 +3100,41 @@ namespace Volian.Controls.Library
|
||||
}
|
||||
else if (_LastProcedureInfo != null)
|
||||
{
|
||||
//If there are enhanced, they will also need deleted, save the ids so that they
|
||||
// can be deleted after this item gets deleted.
|
||||
List<int> enhIds = new List<int>();
|
||||
ProcedureConfig prc = _LastProcedureInfo.MyConfig as ProcedureConfig;
|
||||
foreach (EnhancedDocument ed in prc.MyEnhancedDocuments)
|
||||
if (ed.Type != 0) enhIds.Add(ed.ItemID);
|
||||
// always return false because an event gets fired to delete tree nodes.
|
||||
if (!DeleteItemInfoAndChildren(_LastProcedureInfo)) return false;
|
||||
_LastProcedureInfo = null;
|
||||
foreach (int enhId in enhIds)
|
||||
dlgDelProcReason dlgDPA = new dlgDelProcReason(this); // C2020-038: prompt user for reason
|
||||
DialogResult res = dlgDPA.ShowDialog(this);
|
||||
if (res == DialogResult.OK)
|
||||
{
|
||||
ProcedureInfo pi = ProcedureInfo.Get(enhId);
|
||||
// if the item was displayed in the editor, the 'DeleteItemInfoAndChildren' call
|
||||
// above will go through user interface code that deletes the enhanced, so 'Get'
|
||||
// will return a null (i.e. the data no longer exists).
|
||||
if (pi != null)
|
||||
//If there are enhanced, they will also need deleted, save the ids so that they
|
||||
// can be deleted after this item gets deleted.
|
||||
List<int> enhIds = new List<int>();
|
||||
// C2020-038: request reason for delete procedure so this can be saved in database
|
||||
ProcedureConfig prc = _LastProcedureInfo.MyConfig as ProcedureConfig;
|
||||
prc.General_DelProcReason = DelProcReason;
|
||||
using (Item itm = Item.Get(_LastProcedureInfo.ItemID))
|
||||
{
|
||||
if (!DeleteItemInfoAndChildren(pi)) Console.WriteLine("do an error log item");
|
||||
itm.MyContent.Config = prc.ToString();
|
||||
itm.UserID = Volian.Base.Library.VlnSettings.UserID;
|
||||
itm.Save();
|
||||
}
|
||||
foreach (EnhancedDocument ed in prc.MyEnhancedDocuments)
|
||||
if (ed.Type != 0) enhIds.Add(ed.ItemID);
|
||||
// always return false because an event gets fired to delete tree nodes.
|
||||
if (!DeleteItemInfoAndChildren(_LastProcedureInfo)) return false;
|
||||
|
||||
_LastProcedureInfo = null;
|
||||
foreach (int enhId in enhIds)
|
||||
{
|
||||
ProcedureInfo pi = ProcedureInfo.Get(enhId);
|
||||
// if the item was displayed in the editor, the 'DeleteItemInfoAndChildren' call
|
||||
// above will go through user interface code that deletes the enhanced, so 'Get'
|
||||
// will return a null (i.e. the data no longer exists).
|
||||
if (pi != null)
|
||||
{
|
||||
if (!DeleteItemInfoAndChildren(pi)) Console.WriteLine("do an error log item");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (_LastSectionInfo != null)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user