C2021-026 Parent/Child applicability in RO Editor

This commit is contained in:
2021-07-29 18:28:12 +00:00
parent 697490d5bf
commit ce9e9e182e
16 changed files with 1103 additions and 263 deletions

View File

@@ -1,5 +1,5 @@
/*********************************************************************************************
* Copyright 2002 - Volian Enterprises, Inc. All rights reserved.
* Copyright 2021 - Volian Enterprises, Inc. All rights reserved.
* Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
* ------------------------------------------------------------------------------
* $Workfile: RODBInterface.cs $ $Revision: 48 $
@@ -264,6 +264,7 @@ using Org.Mentalis.Files;
using System.Data.SqlClient;
using System.Collections.Generic;
namespace RODBInterface
{
/// <summary>
@@ -273,7 +274,6 @@ namespace RODBInterface
{
Master = 0, SubDatabase = 1, Schema = 2, Group = 3, GroupSchema = 4, RRO = 5, SchemaStart = 6, SchemaEnd = 7, ConvertedToSql = 8
}
/// <summary>
/// The following class handles generation of sql strings to get/put requested parts of
/// XML RO Tree. And performs the database access using the VLN_DB class.
@@ -314,6 +314,13 @@ namespace RODBInterface
get { return _OnlyConnectOnce; }
set { _OnlyConnectOnce = value; }
}
// C2021-026 used to access in the list of P/C Children
private static string[] _PCChildList = null;
public static string[] PCChildList
{
get { return _PCChildList; }
set { _PCChildList = value; }
}
#endregion
#region abstracts // need these for each method that must be defined for each database type
public abstract string RODB_GetNextGroupTable();
@@ -354,7 +361,6 @@ namespace RODBInterface
}
#region GeneralDB
public void GetDbServerInfo(string ROdir)
{
@@ -504,6 +510,84 @@ namespace RODBInterface
}
return inuse;
}
//C2021-026 adding ability to have field values based on Parent/Child applicability
// This reads the database and returns a list of the field where applicability was enabled
public ArrayList RODB_GetApplicabilityEnabledFields(VlnXmlElement elem, ArrayList fieldsInUse, ref string origApplcFields, bool pcApplicabilityEnabled)
{
ArrayList newApplicList = new ArrayList();
if (!pcApplicabilityEnabled)
{
origApplcFields = null;
return newApplicList;
}
VlnXmlElement startelem = elem;
string atribApplicFields = "ApplicabilityEnabled"; //xml attribute containing list of field recids
// if this element doesn't have any fields in use, walk up the tree until
// we find them.
string applicFields = "";
if (startelem.HasAttribute(atribApplicFields) == false)
{
VlnXmlElement parent;
parent = (VlnXmlElement)startelem.ParentNode;
while (parent != null && applicFields == "")
{
applicFields = parent.GetAttribute(atribApplicFields);
if (parent.Name != "RO_Root")
parent = (VlnXmlElement)parent.ParentNode;
else
parent = null;
}
}
else
applicFields = startelem.GetAttribute(atribApplicFields);
origApplcFields = applicFields; // make a copy to compare to later.
// if there are no fields with applicability (may be inserting a top group)
// return an empty list.
if (applicFields == "") return newApplicList;
// Go through the FieldsInUse list and copy elements to newApplicList
int strpos = 0;
string recid;
recid = applicFields.Substring(strpos, 8);
MyRecID = recid;
while (recid != null)
{
// find it in avail list and add to newApplicList
for (int i = 0; i < fieldsInUse.Count; i++)
{
ROField rof = (ROField)fieldsInUse[i];
string lrecid = rof.GetRecID;
if (lrecid == recid)
{
// add to newApplilcList if it is not already there list
ROField inuserof = new ROField(rof.GetFieldname, rof.GetRecID, rof.GetMasterRecID, rof.GetFieldType);
bool addit = true;
foreach (ROField arof in newApplicList)
{
if (arof.GetRecID == inuserof.GetRecID)
{
addit = false; //this field is already in the list
break;
}
}
if (addit)
newApplicList.Add((object)inuserof);
break;
}
}
strpos = strpos + 9;
if (strpos > applicFields.Length)
recid = null;
else
{
recid = applicFields.Substring(strpos, 8);
}
}
return newApplicList;
}
public string CvtUserFldToFld(string fldname)
{
if (fldname.Length < 2)
@@ -649,6 +733,12 @@ namespace RODBInterface
xmlTextWriter.WriteString(enode.GetAttribute("FieldsInUse"));
xmlTextWriter.WriteEndAttribute();
}
if (enode.HasAttribute("ApplicabilityEnabled")) //C2021-026 save field applicability
{
xmlTextWriter.WriteStartAttribute("ApplicabilityEnabled", null);
xmlTextWriter.WriteString(enode.GetAttribute("ApplicabilityEnabled"));
xmlTextWriter.WriteEndAttribute();
}
if (enode.HasAttribute("GroupMenuItem"))
{
xmlTextWriter.WriteStartAttribute("GroupMenuItem", null);
@@ -755,12 +845,31 @@ namespace RODBInterface
success = RODB_NewSchemaPiece(lrecid, parent.GetAttribute("RecID"), myelem.GetAttribute("Table"), strbld.ToString(), editlevel);
return success;
}
// C2021-026 rename any P/C Child fields
public string DoReplaceParentChildField(string infstr, string oldName, string newName)
{
string rtnInfoStr = infstr;
if (PCChildList == null) return rtnInfoStr;
int pcChildIdx = 0; // children indexing starts at one so initialize with zero
foreach (string chld in PCChildList)
{
pcChildIdx++;
string csufx = string.Format("_PCCHILD{0}", pcChildIdx); // Create child field name
string oldFldNameChild = oldName.Insert(oldName.Length - 1, CvtUserFldToFld(csufx));
string newFldNameChild = newName.Insert(newName.Length - 1, CvtUserFldToFld(csufx));
rtnInfoStr = rtnInfoStr.Replace(oldFldNameChild, newFldNameChild);
}
return rtnInfoStr;
}
public string DoCmbFieldReplace(string repstring, string oname, string nname, string letter)
{
string cmboname, cmbnname;
cmboname = oname.Insert(oname.Length - 1, letter);
cmbnname = nname.Insert(nname.Length - 1, letter);
return (repstring.Replace(cmboname, cmbnname));
string rtnstr = repstring.Replace(cmboname, cmbnname);
rtnstr = DoReplaceParentChildField(rtnstr, cmboname, cmbnname); // C2021-026 create child fields in combo group
return rtnstr;
}
// RODB_UpdateNamesInROs: goes through subtree (top node is 'fld') and if this
@@ -2333,11 +2442,9 @@ namespace RODBInterface
DBE.CommandDispose();
return success;
}
public override bool RODB_ProcessRROFieldChange(VlnXmlElement child, string oldname, string newname, uint editlevel,
VlnStatusMessage StatMsgWindow, bool combofield)
{
bool success;
string str;
string info;
@@ -2464,7 +2571,9 @@ namespace RODBInterface
if (combofield == false)
{
tinfo1 = info.Replace(onameOpen, nnameOpen);
tinfo1 = DoReplaceParentChildField(tinfo1, onameOpen, nnameOpen); //C2021-0226 also update Parent/Child fields
tinfo2 = tinfo1.Replace(onameClose, nnameClose);
tinfo2 = DoReplaceParentChildField(tinfo2, onameClose, nnameClose); //C2021-0226 also update Parent/Child fields
XmlNodeList nodeList;
nodeList = echild.SelectNodes(oldname);
foreach (XmlNode nod in nodeList)
@@ -2499,7 +2608,6 @@ namespace RODBInterface
}
}
}
StatMsgWindow.StatusMessage = echild.GetAttribute("MenuTitle");
str = "UPDATE " + echild.GetAttribute("Table") + " SET Info = '" + tinfo2 + "'";
str = str + ", ModDateTime = '" + dt + "' WHERE RecID = '" + echild.GetAttribute("RecID") + "';";

View File

@@ -2133,7 +2133,9 @@ namespace RODBInterface
if (combofield == false)
{
tinfo1 = info.Replace(onameOpen, nnameOpen);
tinfo1 = DoReplaceParentChildField(tinfo1, onameOpen, nnameOpen); //C2021-0226 also update Parent/Child fields
tinfo2 = tinfo1.Replace(onameClose, nnameClose);
tinfo2 = DoReplaceParentChildField(tinfo2, onameClose, nnameClose); //C2021-0226 also update Parent/Child fields
XmlNodeList nodeList;
nodeList = echild.SelectNodes(oldname);
foreach (XmlNode nod in nodeList)
@@ -2565,6 +2567,7 @@ namespace RODBInterface
return null;
}
}
// C2021-026 read in schema for the "ApplicabilityEnabled" attribute
entireschema = schemastart + entireschema + schemaend;
}
XmlTextReader schemareader = new XmlTextReader(entireschema, XmlNodeType.Element, null);

View File

@@ -1,5 +1,5 @@
/*********************************************************************************************
* Copyright 2002 - Volian Enterprises, Inc. All rights reserved.
* Copyright 2021 - Volian Enterprises, Inc. All rights reserved.
* Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
* ------------------------------------------------------------------------------
* $Workfile: VlnXml.cs $ $Revision: 23 $
@@ -689,13 +689,78 @@ namespace RODBInterface
return rtnval;
}
private ArrayList GetApplcFieldListForElement(RODB roDatabase, VlnXmlElement elem, bool pcApplicability)
{
ArrayList rtnval = null;
ArrayList InUseApplcList = null;
ArrayList AvailList = null;
ArrayList InUseList = null;
string origFieldsInUse = "";
string origApplicFields = "";
ArrayList tmp = roDatabase.RODB_GetFields((VlnXmlElement)elem.ParentNode, (uint)RecordType.Schema);
// put the items in the AvailList box.
if (AvailList == null) AvailList = new ArrayList();
for (int i = 0; i < tmp.Count; i++) AvailList.Add(tmp[i]); // don't modify the list returned from RODB_GetFields since it is part of dictionary
InUseList = roDatabase.RODB_GetFieldsInUse((VlnXmlElement)elem.ParentNode, AvailList, "FieldsInUse", ref origFieldsInUse, false);
InUseApplcList = roDatabase.RODB_GetApplicabilityEnabledFields((VlnXmlElement)elem.ParentNode, InUseList, ref origApplicFields, pcApplicability);
rtnval = new ArrayList();
foreach (ROField rof in InUseApplcList)
rtnval.Add(rof.GetFieldname);
return rtnval;
}
private string GetPCReturnValues(RODB theDb, string[] pcChildern, VlnXmlElement elm, bool PCApplicability, string inusename, string defValue)
{
string applicValues = defValue;
ArrayList FieldsWithApplic = GetApplcFieldListForElement(theDb, elm, PCApplicability);
if (FieldsWithApplic.Contains(CvtFldToUserFld(inusename))) // C2021-026 returns True if field should show Parent/Child Applicability fields
{
XmlNode elmnode = (XmlNode)elm;
XmlNode nd = elmnode.SelectSingleNode(inusename);
string parentName = inusename;
string parentValue = "";
public string GetReturnValue(RODB theDb, string TableName,string RtnValTemplate, ArrayList InUseList, ref ushort ValueType)
if (nd == null)
{
XmlNode radNode = elmnode.FirstChild;
string radNodeName = radNode.Name;
while (radNode != null && !radNodeName.StartsWith(inusename))
{
radNode = radNode.NextSibling;
radNodeName = radNode.Name;
}
parentValue = radNode.InnerText;
parentName = radNodeName;
}
else
parentValue = nd.InnerText;
//applicValues = "";
applicValues = string.Format("<APL DefaultVal={0}", parentValue);
int pcChildIdx = 0;
foreach (string c in pcChildern)
{
//string csufx = CvtUserFldToFld(c);
pcChildIdx++;
string csufx = string.Format("_PCCHILD{0}", pcChildIdx);
applicValues += ",";
XmlNode cn = elmnode.SelectSingleNode(parentName + csufx);
if (cn == null)
applicValues += string.Format("UnitIdx={0} Value={1}", pcChildIdx, parentValue); // use parent value as default
else
applicValues += string.Format("UnitIdx={0} Value={1}", pcChildIdx, cn.InnerText);
}
applicValues += " /APL>";
}
return applicValues;
}
public string GetReturnValue(RODB theDb, string TableName, string RtnValTemplate, ArrayList InUseList, ref ushort ValueType, string[] pcChildern)
{
string RtnValStr = "";
VlnXmlElement elm = this;
StringBuilder strbld = new StringBuilder();
bool PCApplicability = (pcChildern != null && pcChildern.Length > 0);
// Parse the template for the fields and generate a return string
int left = RtnValTemplate.IndexOf("<"); // look for begining of field
int right = -1;
@@ -762,6 +827,8 @@ namespace RODBInterface
}
ValueType |= FldType;
if (PCApplicability)
text = GetPCReturnValues(theDb, pcChildern, elm, PCApplicability, inusename, text); // C2021-026 Get P/C Children return values
strbld.Append(text);
}
else
@@ -789,6 +856,7 @@ namespace RODBInterface
return RtnValStr;
}
public string GetComboFieldValueAndType(XmlNode CurNode, string Fld, ref ushort FldTyp, bool ForMenu)
{
string RtnVal = "";
@@ -929,52 +997,52 @@ namespace RODBInterface
///
// ShowGroupDetail sends to print.tmp the data for a Group level.
private bool ShowGroupDetail(RODB myrodb)
{
ROField rof;
XmlNode nd;
VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument;
string nm;
//private bool ShowGroupDetail(RODB myrodb)
//{
// ROField rof;
// XmlNode nd;
// VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument;
// string nm;
// First get the fields used for this Group.
string tmp=null; // needed for inuse call
ArrayList AvailList = myrodb.RODB_GetFields(this, 0);
ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "GroupFieldsInUse", ref tmp, false);
// // First get the fields used for this Group.
// string tmp=null; // needed for inuse call
// ArrayList AvailList = myrodb.RODB_GetFields(this, 0);
// ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "GroupFieldsInUse", ref tmp, false);
// For each field, print the header (field name) & then print data if it exists.
if (InUseList != null)
{
xmldoc.writeRROBegin();
xmldoc.writeInt(7);
xmldoc.writeText(" ");
// // For each field, print the header (field name) & then print data if it exists.
// if (InUseList != null)
// {
// xmldoc.writeRROBegin();
// xmldoc.writeInt(7);
// xmldoc.writeText(" ");
for (int i=0; i< InUseList.Count; i++)
{
rof = (ROField) InUseList[i];
if (rof.GetFieldname != null)
{
string nm0 = rof.GetFieldname;
nm = rof.MakeFieldName(nm0);
xmldoc.pushHeader(nm0);
// see if it has data in the ro.
nd = this.SelectSingleNode(nm);
// if not found with just the string, search the tree.
if (nd==null)nd = this.SelectSingleNode("*/"+nm);
if (nd == null) // not found, write out a '0'.
xmldoc.writeInt(0);
else
{
VlnXmlElement end;
end = (VlnXmlElement) nd;
xmldoc.writeTextValue(end.InnerText);
}
xmldoc.popHeader();
}
}
xmldoc.writeRROEnd();
}
return true;
}
// for (int i=0; i< InUseList.Count; i++)
// {
// rof = (ROField) InUseList[i];
// if (rof.GetFieldname != null)
// {
// string nm0 = rof.GetFieldname;
// nm = rof.MakeFieldName(nm0);
// xmldoc.pushHeader(nm0);
// // see if it has data in the ro.
// nd = this.SelectSingleNode(nm);
// // if not found with just the string, search the tree.
// if (nd==null)nd = this.SelectSingleNode("*/"+nm);
// if (nd == null) // not found, write out a '0'.
// xmldoc.writeInt(0);
// else
// {
// VlnXmlElement end;
// end = (VlnXmlElement) nd;
// xmldoc.writeTextValue(end.InnerText);
// }
// xmldoc.popHeader();
// }
// }
// xmldoc.writeRROEnd();
// }
// return true;
//}
public XmlNode GetCurrentOfMultiFields(VlnXmlElement CurElement, string FldName)
{
@@ -997,6 +1065,19 @@ namespace RODBInterface
return nd;
}
private bool ContainedInArrayList(ROField rof, ArrayList aryList)
{
bool isInList = false;
foreach (ROField arof in aryList)
{
if (arof.GetRecID == rof.GetRecID)
{
isInList = true;
break;
}
}
return isInList;
}
// ShowRRO writes data for the input RO.
private bool ShowRRO(RODB myrodb, ArrayList headers)
{
@@ -1010,7 +1091,8 @@ namespace RODBInterface
string tmp=null; // needed for inuse call
ArrayList AvailList = myrodb.RODB_GetFields(this, 0);
ArrayList InUseList = myrodb.RODB_GetFieldsInUse(this, AvailList, "FieldsInUse", ref tmp, false);
ArrayList InUseApplcList = myrodb.RODB_GetApplicabilityEnabledFields(this, InUseList, ref tmp, HasApplicabilityEnabled); // C2021-026 get fields that have P/C Children
string defPCROval = "";
// put out the stored headers, i.e. the group titles up the tree.
xmldoc.doHeader(headers);
@@ -1094,13 +1176,33 @@ namespace RODBInterface
if (doingplot)
xmldoc.writePlot(end.InnerText);
else
{
xmldoc.writeTextValue(end.InnerText);
defPCROval = end.InnerText;
}
}
}
// C2021_026 put out PC children values
if (ContainedInArrayList(rof,InUseApplcList))
{
XmlNode pcn;
int pcChildIdx = 0;
foreach (string s in PCChildren)
{
pcChildIdx++;
string pcName = nd.Name + string.Format("_PCCHILD{0}", pcChildIdx); // create child field name
string pcField = rof.MakeFieldName(pcName);
xmldoc.pushHeader(" "+s); // put out the PC Child name (indented 5 spaces) for complete RO Report
// see if it has data in the ro.
pcn = this.SelectSingleNode(pcField);
if (pcn != null)
xmldoc.writeTextValue(pcn.InnerText); // use PC Child value
else
xmldoc.writeTextValue(defPCROval); // use default value
}
}
xmldoc.popHeader();
}
}
xmldoc.writeRROEnd();
}
@@ -1184,12 +1286,21 @@ namespace RODBInterface
headers.RemoveAt(headers.Count-1);
return true;
}
private static string[] PCChildren = null; //C2021-026 holds list of P/C children names
public bool HasApplicabilityEnabled
{
get
{
return (PCChildren != null && PCChildren.Length > 0);
}
}
// put this element, and if a group all it's subelements out to the 'print.tmp'
// file for complete reports.
public bool Show(RODB myrodb, ArrayList headers, VlnStatusMessage showStat)
public bool Show(RODB myrodb, ArrayList headers, VlnStatusMessage showStat, string [] pcChildren)
{
bool success;
PCChildren = pcChildren; // C2021-026 list of P/C children
VlnXmlDocument xmldoc = (VlnXmlDocument) this.OwnerDocument;
success = xmldoc.OpenTemp();
if (success==false) return false;