C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)

Initial check-in / adding ui options / base for export
This commit is contained in:
2025-06-30 14:32:24 -04:00
parent 9ef9dcd7b9
commit 92522b1229
6 changed files with 552 additions and 187 deletions

View File

@@ -164,6 +164,9 @@
<Compile Include="dlgCheckedOutProcedure.designer.cs">
<DependentUpon>dlgCheckedOutProcedure.cs</DependentUpon>
</Compile>
<Compile Include="dlgExportImportEP.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="dlgMSWordMessage.cs">
<SubType>Form</SubType>
</Compile>

View File

@@ -29,6 +29,7 @@ namespace VEPROMS
}
private bool _ConvertROsToTextDuringImport = false;
private bool _ConvertROsAndTransitionsToText = false; // set to true when Approval creates an Export file
protected bool _ExportBothConvertedandNot = false; // set to true when Electronic Procedure export
// B2016-225 notify user when Transitions and/or ROs are converted to text
private bool _DidConvertTransitionsToText = false;
@@ -64,7 +65,7 @@ namespace VEPROMS
private FolderInfo MyFolder = null;
private DocVersionInfo MyDocVersion = null;
private ProcedureInfo MyProcedure = null;
private XmlAttribute AddAttribute(XmlDocument xd, string name, string value)
protected XmlAttribute AddAttribute(XmlDocument xd, string name, string value)
{
XmlAttribute xa = xd.CreateAttribute(name);
xa.InnerText = value;
@@ -2423,9 +2424,17 @@ namespace VEPROMS
if (ii.ItemAnnotationCount > 0)
foreach (AnnotationInfo ai in ii.ItemAnnotations)
ExportAnnotation(xe, ai, "annotation");
ExportEPAnnotationInfo(xe, ii);
}
private void ExportItemAudits(XmlElement xn, ItemInfo ii)
protected virtual void ExportEPAnnotationInfo(XmlElement xe, ItemInfo ii)
{
//do nothing - this will be for Electronic procedures only
//and handled/overridden in dlgExportEP.cs
}
private void ExportItemAudits(XmlElement xn, ItemInfo ii)
{
if (cbxExportAudits.Checked)
{
@@ -2566,6 +2575,7 @@ namespace VEPROMS
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "dts", ci.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff")));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "userid", ci.UserID.ToString()));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "formatfilename", formatFileName));
if (_ExportBothConvertedandNot) xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "textwithlinks", ci.Text));
//content audits
ExportContentAudits(xe, ci);
@@ -2652,6 +2662,7 @@ namespace VEPROMS
MyWriter.WriteAttributeString("dts", ci.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff"));
MyWriter.WriteAttributeString("userid", ci.UserID.ToString());
MyWriter.WriteAttributeString("formatfilename", formatFileName);
if (_ExportBothConvertedandNot) MyWriter.WriteAttributeString("textwithlinks", ci.Text);
if (ci.ContentTransitionCount > 0)
foreach (TransitionInfo ti in ci.ContentTransitions)
@@ -2699,7 +2710,8 @@ namespace VEPROMS
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "config", gi.Config));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "dts", gi.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff")));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "userid", gi.UserID.ToString()));
if (_ExportBothConvertedandNot) xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "datawithlinks", gi.Data));
//grid audits
ExportGridAudits(xe, gi);
xn.AppendChild(xe);
@@ -2758,6 +2770,7 @@ namespace VEPROMS
MyWriter.WriteAttributeString("config", gi.Config);
MyWriter.WriteAttributeString("dts", gi.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff"));
MyWriter.WriteAttributeString("userid", gi.UserID.ToString());
if (_ExportBothConvertedandNot) MyWriter.WriteAttributeString("datawithlinks", gi.Data);
MyWriter.WriteEndElement();
}
@@ -2932,7 +2945,8 @@ namespace VEPROMS
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "dts", di.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff")));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "userid", di.UserID.ToString()));
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "fileextension", di.FileExtension));
if (_ExportBothConvertedandNot) xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "doccontentwithlinks", Convert.ToBase64String(di.DocContent)));
//document audits
ExportDocumentAudits(xe, di);
xn.AppendChild(xe);
@@ -2998,6 +3012,7 @@ namespace VEPROMS
MyWriter.WriteAttributeString("dts", di.DTS.ToString("MM/dd/yyyy HH:mm:ss.fff"));
MyWriter.WriteAttributeString("userid", di.UserID.ToString());
MyWriter.WriteAttributeString("fileextension", di.FileExtension);
if (_ExportBothConvertedandNot) MyWriter.WriteAttributeString("doccontentwithlinks", Convert.ToBase64String(di.DocContent));
MyWriter.WriteEndElement();
}

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using VEPROMS.CSLA.Library;
namespace VEPROMS
{
//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
//class inherits from normal import/export form
//then adds additional functionality
public partial class dlgExportImportEP : dlgExportImport
{
private readonly AnnotationTypeInfo _AnnotationType;
private string multiseparator = ",";
private static Regex _ROAccPageTokenPattern = new Regex("[<][^<>-]+-[^<>]+[>]");
public dlgExportImportEP(string mode, FolderInfo folderInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId) : base(mode, folderInfo, myFrmVEPROMS, (E_UCFImportOptions) 0)
{
_AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
_ExportBothConvertedandNot = true;
DocReplace = new Dictionary<int, byte[]>();
FormClosed += OnClose;
Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {folderInfo.Name}";
}
public dlgExportImportEP(string mode, DocVersionInfo docVersionInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId) : base(mode, docVersionInfo, myFrmVEPROMS, (E_UCFImportOptions)0)
{
_AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
_ExportBothConvertedandNot = true;
DocReplace = new Dictionary<int, byte[]>();
FormClosed += OnClose;
Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {docVersionInfo.Name} of {docVersionInfo.MyFolder.Name}";
}
public dlgExportImportEP(string mode, ProcedureInfo procedureInfo, frmVEPROMS myFrmVEPROMS, int annotationTypeId) : base(mode, procedureInfo, myFrmVEPROMS, (E_UCFImportOptions)0)
{
_AnnotationType = AnnotationTypeInfo.Get(annotationTypeId);
_ExportBothConvertedandNot = true;
DocReplace = new Dictionary<int, byte[]>();
FormClosed += OnClose;
Text = $"{mode} Electronic Procedure ({_AnnotationType.Name}) Dialog for {procedureInfo.DisplayNumber}";
}
//Overridden function to handle export of EP data
protected override void ExportEPAnnotationInfo(XmlElement xe, ItemInfo ii)
{
//switch to handle customizations for different formats
switch (ii.ActiveFormat.PlantFormat.EPFormatFiles.Find(x => x.AnnotationTypeID == _AnnotationType.TypeID)?.Name)
{
default:
ExportEPAnnotationInfo_Default(xe, ii);
break;
}
}
//default export of EP Data
private void ExportEPAnnotationInfo_Default(XmlElement xe, ItemInfo ii)
{
//Add tab text to item
string steptab = Volian.Print.Library.PDFReport.BuildStepTab(ii);
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "StepTab", steptab));
//get first transition in item and add it as an xml element
if (ii.MyContent.ContentTransitionCount > 0)
{
TransitionInfo ct = ii.MyContent.ContentTransitions[0];
xe.Attributes.SetNamedItem(AddAttribute(xe.OwnerDocument, "TransitionToItemID", ct.ToID.ToString()));
}
//export EP annotation details under an EPInfo node
if (ii.ItemAnnotations != null)
{
XmlElement xepinfo = xe.OwnerDocument.CreateElement("EPInfo");
EPFields myEPFields = ii.GetValidEPFields(_AnnotationType.TypeID);
ROFSTLookup lookup = ii.MyDocVersion.DocVersionAssociations[0].MyROFst.GetROFSTLookup(ii.MyDocVersion);
//For each annotation in the item that is of the current EP Annotation type
foreach (var EPAnnotation in ii.ItemAnnotations.Where(x => x.TypeID == _AnnotationType.TypeID))
{
var EPAnnotationConfig = new AnnotationConfig(EPAnnotation.Config);
XmlElement xepdetails = xe.OwnerDocument.CreateElement("Details");
//include the annotation ID for reference
xepdetails.Attributes.SetNamedItem(AddAttribute(xepdetails.OwnerDocument, "AnnotationID", EPAnnotation.AnnotationID.ToString()));
//loop through each EP Field - name the xml elements the EP.name
foreach (EPField EP in myEPFields)
{
string val = EPAnnotationConfig.GetValue("EP", EP.name);
XmlElement xindivid = xe.OwnerDocument.CreateElement(EP.name);
//need to resolve ROs ROSingle, ROMulti, in text
//get values
//should we export blank?
//
switch (EP.type.ToLower())
{
case "text":
//for text, check if any embedded ROs
//if none, set the xml element to the text
//otherwise resolve the Ros
MatchCollection matches = _ROAccPageTokenPattern.Matches(val);
if (matches.Count == 0)
{
xindivid.InnerText = val;
}
else
{
//resolve ROs
//text ROs will replace the AccID key in the text
//for binary objects like images,
//we will keep the AccID in the text and output the binary as a separate child
//XML element with the same xml name as the AccID
foreach (Match m in matches)
{
ROFSTLookup.rochild roc = lookup.GetROChildByAccPageID(m.Groups[1].Value);
if (roc.type == 8) // Exclude replacing Images since are binary - for those, add a sub item
{
XmlElement xroid = xindivid.OwnerDocument.CreateElement(m.Groups[1].Value);
xroid.InnerText = roc.value;
xindivid.AppendChild(xroid);
}
else if (!string.IsNullOrEmpty(roc.value))
{
bool convertCaretToDeltaSymbol = (ii.ActiveSection != null) && ii.ActiveSection.ActiveFormat.PlantFormat.FormatData.SectData.ConvertCaretToDelta;
string rocvalue = roc.value.Replace("`", "\xB0");
rocvalue = rocvalue.Replace("\xF8", "\xB0");
rocvalue = rocvalue.Replace("\x7F", "\x394"); //delta
if (convertCaretToDeltaSymbol) rocvalue = rocvalue.Replace("^", "\x394"); // delta
val = val.Replace($"<{m.Groups[1].Value}>", rocvalue);
}
}
xindivid.InnerText = val;
}
break;
case "rosingle":
//Get the output columns from the EPFormatFile
//set the "Item" nodes value = to those resolved items
//separated by multiseparator
XmlElement xindivid_rosingle = xindivid.OwnerDocument.CreateElement("Item");
xindivid_rosingle.Attributes.SetNamedItem(AddAttribute(xindivid_rosingle.OwnerDocument, "ROID", val));
List<string> ro_single_tmp = EP.getROValuesList(EPAnnotation, val);
xindivid_rosingle.InnerText = String.Join(multiseparator, ro_single_tmp.ToArray());
xindivid.AppendChild(xindivid_rosingle);
break;
case "romulti":
//Get the output columns from the EPFormatFile
//create an "Item" subnode for each selected RO
//set the nodes value = to those resolved items
//separated by multiseparator
foreach (string ival in val.Split(multiseparator.ToCharArray()))
{
XmlElement xindivid_romulti = xindivid.OwnerDocument.CreateElement("Item");
xindivid_romulti.Attributes.SetNamedItem(AddAttribute(xindivid_romulti.OwnerDocument, "ROID", ival));
List<string> ro_multi_tmp = EP.getROValuesList(EPAnnotation, ival);
xindivid_romulti.InnerText = String.Join(multiseparator, ro_multi_tmp.ToArray());
xindivid.AppendChild(xindivid_romulti);
}
break;
case "tableinput":
xindivid.InnerText = val;
break;
default:
xindivid.InnerText = val;
break;
}
xepdetails.AppendChild(xindivid);
}
xepinfo.AppendChild(xepdetails);
}
xe.AppendChild(xepinfo);
}
}
//clear objects to release memory
private void OnClose(object sender, EventArgs e)
{
DocReplace.Clear();
DocReplace = null;
}
}
}

View File

@@ -708,15 +708,32 @@ namespace VEPROMS
else
{
int ownerid = MySessionInfo.CheckOutItem(fi.FolderID, CheckOutType.Session);
dlgExportImport dlg = new dlgExportImport(args.Index == 0 ? "Export" : "Import", fi, this, (E_UCFImportOptions)Properties.Settings.Default.UCFImportOpt);//Added frmVEPROMS Parameter
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
if (args.Index == 1 && dlg.MyNewFolder != null)
//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
//form for exporting Electronic Procedures from FolderInfo
if (args.AnnotationTypeId > 0)
{
tv.AddNewNode(dlg.MyNewFolder);
dlgExportImportEP dlg = new dlgExportImportEP(args.Index == 0 ? "Export" : "Import", fi, this, args.AnnotationTypeId);
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
if (args.Index == 1 && dlg.MyNewFolder != null)
{
tv.AddNewNode(dlg.MyNewFolder);
}
}
else
{
dlgExportImport dlg = new dlgExportImport(args.Index == 0 ? "Export" : "Import", fi, this, (E_UCFImportOptions)Properties.Settings.Default.UCFImportOpt);//Added frmVEPROMS Parameter
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
if (args.Index == 1 && dlg.MyNewFolder != null)
{
tv.AddNewNode(dlg.MyNewFolder);
}
}
}
}
@@ -742,18 +759,40 @@ namespace VEPROMS
int ownerid = MySessionInfo.CheckOutItem(dvi.VersionID, CheckOutType.DocVersion);
dlgExportImport dlg = new dlgExportImport("Import", dvi, this, (E_UCFImportOptions)Properties.Settings.Default.UCFImportOpt);//Added frmVEPROMS Parameter
dlg.MyNewProcedure = null;
dlg.ExternalTransitionItem = null;
dlg.ShowDialog(this);
//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
//form for exporting Electronic Procedures from DocVersionInfo
if (args.AnnotationTypeId > 0)
{
dlgExportImportEP dlg = new dlgExportImportEP(args.Index == 0 ? "Export" : "Import", dvi, this, args.AnnotationTypeId);
dlg.MyNewProcedure = null;
dlg.ExternalTransitionItem = null;
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
MySessionInfo.CheckInItem(ownerid);
if (dlg.MyNewProcedure != null)
tv.AddNewNode(dlg.MyNewProcedure);
if (dlg.MyNewProcedure != null)
tv.AddNewNode(dlg.MyNewProcedure);
if (dlg.ExternalTransitionItem != null)
tc.OpenItem(dlg.ExternalTransitionItem);
}
else
{
dlgExportImport dlg = new dlgExportImport("Import", dvi, this, (E_UCFImportOptions)Properties.Settings.Default.UCFImportOpt);//Added frmVEPROMS Parameter
dlg.MyNewProcedure = null;
dlg.ExternalTransitionItem = null;
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
if (dlg.MyNewProcedure != null)
tv.AddNewNode(dlg.MyNewProcedure);
if (dlg.ExternalTransitionItem != null)
tc.OpenItem(dlg.ExternalTransitionItem);
}
if (dlg.ExternalTransitionItem != null)
tc.OpenItem(dlg.ExternalTransitionItem);
}
}
@@ -769,10 +808,24 @@ namespace VEPROMS
else
{
int ownerid = MySessionInfo.CheckOutItem(pi.ItemID, CheckOutType.Procedure);
dlgExportImport dlg = new dlgExportImport("Export", pi, this, (E_UCFImportOptions)0);//Added frmVEPROMS Parameter
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
//C2025-024 Electronic Procedures - Phase 2 (PROMS XML output)
//form for exporting Electronic Procedures from ProcedureInfo
if (args.AnnotationTypeId > 0)
{
dlgExportImportEP dlg = new dlgExportImportEP("Export", pi, this, args.AnnotationTypeId);
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
}
else
{
dlgExportImport dlg = new dlgExportImport("Export", pi, this, (E_UCFImportOptions)0);//Added frmVEPROMS Parameter
dlg.ShowDialog(this);
MySessionInfo.CheckInItem(ownerid);
}
}
}
}
@@ -1216,7 +1269,7 @@ namespace VEPROMS
//Print Section
//C2025-028 Add a Quick Print Section option
void tv_PrintSection(object sender, vlnTreeEventArgs args)
{
PrintSection(sender, args, false);
@@ -1226,7 +1279,7 @@ namespace VEPROMS
PrintSection(sender, args, true);
}
void PrintSection(object sender, vlnTreeEventArgs args, bool quickprint)
void PrintSection(object sender, vlnTreeEventArgs args, bool quickprint)
{
try
{
@@ -2195,7 +2248,7 @@ namespace VEPROMS
this.superTooltip1.SetSuperTooltip(btnResetSecurity, new SuperTooltipInfo("Reset Security", "", "WARNING this will \nREMOVE ALL PROMS USERS and Reset to the\nOriginal Volian Defaults", null, null, eTooltipColor.Gray));
this.superTooltip1.SetSuperTooltip(btnAdministrativeTools, new SuperTooltipInfo("Administrative Tools", "", "Open the PROMS Adminstration Tools Window", null, null, eTooltipColor.Gray));
this.superTooltip1.SetSuperTooltip(btnUpdateFormats, new SuperTooltipInfo("Update Formats", "", "Install New Formats \n or Re-Install Formats", null, null, eTooltipColor.Gray));
try
{
MyUserInfo = UserInfo.GetByUserID(VlnSettings.UserID);