public void TestLoopThroughUINavigation() { TLogging.Log("Running test 'TestLoopThroughUINavigation'..." + Environment.NewLine); // get all nodes that have an attribute ActionOpenScreen XPathExpression expr = FNavigator.Compile("//*[@ActionOpenScreen]"); XPathNodeIterator iterator = FNavigator.Select(expr); while (iterator.MoveNext()) { if (iterator.Current is IHasXmlNode) { XmlNode ActionNode = ((IHasXmlNode)iterator.Current).GetNode(); // look at the permissions module the window came from string Module = TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired"); TLogging.Log(String.Format("{0,-36}{1,-36}{2}", ActionNode.Name, ActionNode.Attributes["ActionOpenScreen"].Value, Module)); } } }
/// creates a file with enums in Shared and one file per submodule in Server for cached tables public static void WriteCachedTables(TDataDefinitionStore AStore, string ACacheYamlFilename, string ASharedPath, string ATemplateDir) { // Load yaml file with list of tables that should be cached TYml2Xml ymlParser = new TYml2Xml(ACacheYamlFilename); XmlDocument xmlDoc = ymlParser.ParseYML2XML(); XmlNode module = xmlDoc.DocumentElement.FirstChild.FirstChild; while (module != null) { XmlNode subModule = module.FirstChild; bool severalSubModules = (subModule != null && subModule.NextSibling != null); // write the shared file with the enum definitions ProcessTemplate SharedTemplate = new ProcessTemplate(ATemplateDir + Path.DirectorySeparatorChar + "ORM" + Path.DirectorySeparatorChar + "Cacheable.Shared.cs"); SharedTemplate.SetCodelet("GPLFILEHEADER", ProcessTemplate.LoadEmptyFileComment(ATemplateDir)); // SharedTemplate.SetCodelet("NAMESPACE", "Ict.Petra.Shared.M" + module.Name); SharedTemplate.SetCodelet("NAMESPACE", "Ict.Petra.Shared"); while (subModule != null) { List <string> UsingNamespaces = new List <string>(); // write the server file for each submodule ProcessTemplate ServerTemplate = new ProcessTemplate(ATemplateDir + Path.DirectorySeparatorChar + "ORM" + Path.DirectorySeparatorChar + "Cacheable.Server.cs"); ServerTemplate.SetCodelet("GPLFILEHEADER", ProcessTemplate.LoadEmptyFileComment(ATemplateDir)); ServerTemplate.SetCodelet("NAMESPACE", "Ict.Petra.Server.M" + module.Name + "." + subModule.Name + ".Cacheable"); ServerTemplate.SetCodelet("SUBNAMESPACE", "M" + module.Name + "." + subModule.Name); ServerTemplate.SetCodelet("CACHEABLECLASS", "T" + module.Name + "Cacheable"); ServerTemplate.SetCodelet("SUBMODULE", subModule.Name); ServerTemplate.SetCodelet("GETCALCULATEDLISTFROMDB", ""); ServerTemplate.SetCodelet("LEDGERGETCACHEABLE", ""); ServerTemplate.SetCodelet("LEDGERSAVECACHEABLE", ""); if (!severalSubModules) { // for MCommon ServerTemplate.SetCodelet("NAMESPACE", "Ict.Petra.Server.M" + module.Name + ".Cacheable"); ServerTemplate.SetCodelet("SUBNAMESPACE", "M" + module.Name); ServerTemplate.SetCodelet("CACHEABLECLASS", "TCacheable"); } ProcessTemplate snippetSubmodule = SharedTemplate.GetSnippet("SUBMODULEENUM"); snippetSubmodule.SetCodelet("SUBMODULE", subModule.Name); snippetSubmodule.SetCodelet("MODULE", module.Name); ProcessTemplate snippetLedgerGetTable = null; ProcessTemplate snippetLedgerSaveTable = null; XmlNode TableOrListElement = subModule.FirstChild; while (TableOrListElement != null) { XmlNode enumElement = TableOrListElement.FirstChild; while (enumElement != null) { bool DependsOnLedger = false; if (TYml2Xml.GetAttributeRecursive(enumElement, "DependsOnLedger") == "true") { if (snippetLedgerGetTable == null) { snippetLedgerGetTable = ServerTemplate.GetSnippet("LEDGERGETCACHEABLE"); snippetLedgerGetTable.SetCodelet("SUBMODULE", subModule.Name); } if ((snippetLedgerSaveTable == null) && (TableOrListElement.Name == "DatabaseTables")) { snippetLedgerSaveTable = ServerTemplate.GetSnippet("LEDGERSAVECACHEABLE"); snippetLedgerSaveTable.SetCodelet("SUBMODULE", subModule.Name); } DependsOnLedger = true; ServerTemplate.SetCodelet("WITHLEDGER", "true"); } ProcessTemplate snippetElement = SharedTemplate.GetSnippet("ENUMELEMENT"); if ((enumElement.NextSibling == null) && ((TableOrListElement.NextSibling == null) || (TableOrListElement.NextSibling.FirstChild == null))) { snippetElement = SharedTemplate.GetSnippet("ENUMELEMENTLAST"); } string Comment = TXMLParser.GetAttribute(enumElement, "Comment"); if (TableOrListElement.Name == "DatabaseTables") { TTable Table = AStore.GetTable(enumElement.Name); string Namespace = "Ict.Petra.Shared." + TTable.GetNamespace(Table.strGroup) + ".Data"; if (!UsingNamespaces.Contains(Namespace)) { UsingNamespaces.Add(Namespace); } Namespace = "Ict.Petra.Server." + TTable.GetNamespace(Table.strGroup) + ".Validation"; if (!UsingNamespaces.Contains(Namespace)) { UsingNamespaces.Add(Namespace); } Namespace = "Ict.Petra.Server." + TTable.GetNamespace(Table.strGroup) + ".Data.Access"; if (!UsingNamespaces.Contains(Namespace)) { UsingNamespaces.Add(Namespace); } if (Table == null) { throw new Exception("Error: cannot find table " + enumElement.Name + " for caching in module " + module.Name); } if (Comment.Length == 0) { Comment = Table.strDescription; } } if (Comment.Length == 0) { Comment = "todoComment"; } snippetElement.SetCodelet("ENUMCOMMENT", Comment); string enumName = enumElement.Name; if (TXMLParser.HasAttribute(enumElement, "Enum")) { enumName = TXMLParser.GetAttribute(enumElement, "Enum"); } else if (TableOrListElement.Name == "DatabaseTables") { string character2 = enumElement.Name.Substring(1, 1); if (character2.ToLower() == character2) { // this is a table name that has a 2 digit prefix enumName = enumElement.Name.Substring(2) + "List"; } else { enumName = enumElement.Name.Substring(1) + "List"; } } snippetElement.SetCodelet("ENUMNAME", enumName); snippetElement.SetCodelet("DATATABLENAME", enumElement.Name); snippetSubmodule.InsertSnippet("ENUMELEMENTS", snippetElement); if (TableOrListElement.Name == "DatabaseTables") { ProcessTemplate snippetLoadTable = ServerTemplate.GetSnippet("LOADTABLE"); if (DependsOnLedger) { snippetLoadTable = ServerTemplate.GetSnippet("LOADTABLEVIALEDGER"); } snippetLoadTable.SetCodelet("ENUMNAME", enumName); snippetLoadTable.SetCodelet("DATATABLENAME", enumElement.Name); if (DependsOnLedger) { snippetLedgerGetTable.InsertSnippet("LOADTABLESANDLISTS", snippetLoadTable); } else { ServerTemplate.InsertSnippet("LOADTABLESANDLISTS", snippetLoadTable); } ProcessTemplate snippetSaveTable = ServerTemplate.GetSnippet("SAVETABLE"); snippetSaveTable.SetCodelet("ENUMNAME", enumName); snippetSaveTable.SetCodelet("SUBMODULE", subModule.Name); snippetSaveTable.SetCodelet("DATATABLENAME", enumElement.Name); if (DependsOnLedger) { snippetLedgerSaveTable.InsertSnippet("SAVETABLE", snippetSaveTable); } else { ServerTemplate.InsertSnippet("SAVETABLE", snippetSaveTable); } ProcessTemplate snippetDataValidation = ServerTemplate.GetSnippet("DATAVALIDATION"); snippetDataValidation.SetCodelet("ENUMNAME", enumName); snippetDataValidation.SetCodelet("DATATABLENAME", enumElement.Name); if (DependsOnLedger) { snippetLedgerSaveTable.InsertSnippet("DATAVALIDATION", snippetDataValidation); } else { ServerTemplate.InsertSnippet("DATAVALIDATION", snippetDataValidation); } } else { ProcessTemplate snippetLoadList = ServerTemplate.GetSnippet("LOADCALCULATEDLIST"); if (DependsOnLedger) { snippetLoadList = ServerTemplate.GetSnippet("LOADCALCULATEDLISTFORLEDGER"); } snippetLoadList.SetCodelet("ENUMNAME", enumName); snippetLoadList.SetCodelet("CALCULATEDLISTNAME", enumName); if (DependsOnLedger) { snippetLedgerGetTable.InsertSnippet("LOADTABLESANDLISTS", snippetLoadList); } else { ServerTemplate.InsertSnippet("LOADTABLESANDLISTS", snippetLoadList); } if (TYml2Xml.GetAttributeRecursive(enumElement, "IsStorableToDBTable") != String.Empty) { ProcessTemplate snippetSaveTable = ServerTemplate.GetSnippet("SAVETABLE"); snippetSaveTable.SetCodelet("ENUMNAME", enumName); snippetSaveTable.SetCodelet("SUBMODULE", subModule.Name); snippetSaveTable.SetCodelet("DATATABLENAME", TYml2Xml.GetAttributeRecursive(enumElement, "IsStorableToDBTable")); if (DependsOnLedger) { snippetLedgerSaveTable.InsertSnippet("SAVETABLE", snippetSaveTable); } else { ServerTemplate.InsertSnippet("SAVETABLE", snippetSaveTable); } ProcessTemplate snippetDataValidation = ServerTemplate.GetSnippet("DATAVALIDATION"); snippetDataValidation.SetCodelet("ENUMNAME", enumName); snippetDataValidation.SetCodelet("DATATABLENAME", TYml2Xml.GetAttributeRecursive(enumElement, "IsStorableToDBTable")); if (DependsOnLedger) { snippetLedgerSaveTable.InsertSnippet("DATAVALIDATION", snippetDataValidation); } else { ServerTemplate.InsertSnippet("DATAVALIDATION", snippetDataValidation); } } } enumElement = enumElement.NextSibling; if (enumElement != null) { snippetSubmodule.AddToCodelet("ENUMELEMENTS", Environment.NewLine); } } TableOrListElement = TableOrListElement.NextSibling; } SharedTemplate.InsertSnippet("ENUMS", snippetSubmodule); if (snippetLedgerGetTable != null) { ServerTemplate.InsertSnippet("LEDGERGETCACHEABLE", snippetLedgerGetTable); } if (snippetLedgerSaveTable != null) { ServerTemplate.InsertSnippet("LEDGERSAVECACHEABLE", snippetLedgerSaveTable); } ServerTemplate.SetCodelet("USINGNAMESPACES", string.Empty); foreach (string UsingNamespace in UsingNamespaces) { ServerTemplate.AddToCodelet("USINGNAMESPACES", "using " + UsingNamespace + ";" + Environment.NewLine); } string path = ASharedPath + Path.DirectorySeparatorChar + ".." + Path.DirectorySeparatorChar + "Server" + Path.DirectorySeparatorChar + "lib" + Path.DirectorySeparatorChar + "M" + module.Name + Path.DirectorySeparatorChar; if (File.Exists(path + "Cacheable.ManualCode.cs")) { path += "Cacheable-generated.cs"; } else { if (File.Exists(path + "data" + Path.DirectorySeparatorChar + subModule.Name + "." + "Cacheable.ManualCode.cs")) { path += "data" + Path.DirectorySeparatorChar + subModule.Name + "." + "Cacheable-generated.cs"; } else if (File.Exists(path + "data" + Path.DirectorySeparatorChar + "Cacheable.ManualCode.cs")) { path += "data" + Path.DirectorySeparatorChar + "Cacheable-generated.cs"; } else { path += subModule.Name + "." + "Cacheable-generated.cs"; } } ServerTemplate.FinishWriting(path, ".cs", true); subModule = subModule.NextSibling; } SharedTemplate.FinishWriting(ASharedPath + Path.DirectorySeparatorChar + "M" + module.Name + ".Cacheable-generated.cs", ".cs", true); module = module.NextSibling; } }
/// <summary> /// This is client-side code to check user permissions for a module. It does NOT use the PermissionsRequired attribute of the UINavigation file. /// It does use the Namespace name for the action that has been clicked and a switch statement with hard-coded permissions. /// It is not a substitute for server side permissions-checking but it DOES provide a **STRONG** check on the client side that the user has not /// tampered with the UINavigation file itself. /// With this check the user can neither modify the PermissionsRequired attribute nor move the task to a different place in the file! /// </summary> /// <param name="ANode">The node that contains the namespace and the ActionOpenScreen or ActionClick</param> /// <returns></returns> public static bool CheckUserAccessToModuleUsingModuleNamespaceName(XmlNode ANode) { bool ret = true; string modulePermissionRequired = string.Empty; string namespaceName = TYml2Xml.GetAttributeRecursive(ANode, "Namespace"); string actionScreenClass = TYml2Xml.GetAttributeRecursive(ANode, "ActionOpenScreen"); string actionClick = TYml2Xml.GetAttributeRecursive(ANode, "ActionClick"); string actionContext = TYml2Xml.GetAttributeRecursive(ANode, "Context"); if (namespaceName.Contains("Client.MPartner.Gui") || namespaceName.EndsWith("Client.MReporting.Gui.MPartner")) { // Although this looks like Partner there are some subtle variations, which we test below modulePermissionRequired = PETRAMODULE_PTNRUSER; } // The order of these if/else clauses is important!! if (namespaceName.Contains("Client.MPersonnel.Gui") || namespaceName.Contains("Client.MReporting.Gui.MPersonnel") || (actionContext == "Personnel") || (actionContext == "LongTermApp") || (actionContext == "ShortTermApp") || actionClick.StartsWith("TPersonnelMain.")) { // Note that this includes Personnel Extracts and MCommon items modulePermissionRequired = PETRAMODULE_PERSONNEL; } else if (namespaceName.Contains("Client.MFinance.Gui.ICH")) { // ICH is associated with MonthEnd, so needs Finance-2 modulePermissionRequired = string.Format("AND({0},{1})", PETRAMODULE_FINANCE1, PETRAMODULE_FINANCE2); } else if (namespaceName.Contains("Client.MFinance.Gui") || (actionContext == "Finance") || actionClick.StartsWith("TFinanceMain.")) { // This includes Finance extracts and MCommon items if (actionScreenClass == "TPeriodEndMonth") { // MonthEnd needs Finance-2 modulePermissionRequired = string.Format("AND({0},{1})", PETRAMODULE_FINANCE1, PETRAMODULE_FINANCE2); } else if ((actionScreenClass == "TPeriodEndYear") || (actionScreenClass == "TFrmGLCreateLedgerDialog") || actionClick.EndsWith("DeleteLedger")) { // These need Finance-3 modulePermissionRequired = string.Format("AND({0},{1})", PETRAMODULE_FINANCE1, PETRAMODULE_FINANCE3); } else { modulePermissionRequired = PETRAMODULE_FINANCE1; } } else if (namespaceName.EndsWith("Client.MReporting.Gui.MFinance")) { if ((actionScreenClass == "TFrmStewardshipForPeriod") || (actionScreenClass == "TFrmGiftBatchDetail") || (actionScreenClass == "TFrmAP_RemittanceAdvice")) { // These screens are reports but are actually screens to re-print something modulePermissionRequired = PETRAMODULE_FINANCE1; } else { modulePermissionRequired = string.Format("AND({0},{1})", PETRAMODULE_FINANCE1, PETRAMODULE_FINANCERPT); } } else if (namespaceName.Contains("Client.MCommon.Gui")) { // Now we have to handle MCommon - mostly these are Partner screens if (actionScreenClass == "TFrmCurrencySetup") { modulePermissionRequired = PETRAMODULE_FINANCE1; } else if (actionScreenClass.Contains("Personnel")) { modulePermissionRequired = PETRAMODULE_PERSONNEL; } else { modulePermissionRequired = PETRAMODULE_PTNRUSER; } } else if (namespaceName.Contains("Client.MFinDev.Gui") || namespaceName.EndsWith("Client.MReporting.Gui.MFinDev")) { modulePermissionRequired = PETRAMODULE_DEVUSER; } else if (namespaceName.Contains("Client.MConference.Gui") || namespaceName.EndsWith("Client.MReporting.Gui.MConference")) { modulePermissionRequired = PETRAMODULE_CONFERENCE; } else if (namespaceName.Contains("Client.MSysMan.Gui")) { if ((actionScreenClass == "TFrmUserPreferencesDialog") || actionClick.EndsWith(".SetUserPassword") || actionClick.EndsWith(".RunGlobalDataUpdater")) { // No special permissions required } else if (actionScreenClass == "TFrmIntranetExportDialog") { modulePermissionRequired = string.Format("OR({0},{1},{2})", PETRAMODULE_PTNRUSER, PETRAMODULE_FINANCE1, PETRAMODULE_PERSONNEL); } else { modulePermissionRequired = PETRAMODULE_SYSADMIN; } } // Now run the permissions check if ((modulePermissionRequired != string.Empty) && (FCheckUserModulePermissions != null)) { Console.WriteLine("Launching {0} -- Checking for permission: {1}", ANode.Name, modulePermissionRequired); try { FCheckUserModulePermissions(modulePermissionRequired, "Launch Task " + MODULE_ACCESS_MANAGER_CLIENT_PROXY); } catch (ESecurityModuleAccessDeniedException ex) { ret = false; if (FSecurityAccessDeniedMessage != null) { FSecurityAccessDeniedMessage(ex, null); } } } return(ret); }
/// <summary> /// Execute action from the navigation tree. /// </summary> /// <returns>The error or status message.</returns> public static string ExecuteAction(XmlNode node, Form AParentWindow) { bool FormWasAlreadyOpened = false; if (!FHasAccessPermission(node, FUserId, true)) { return(Catalog.GetString("Sorry, you don't have enough permissions to do this")); } string strNamespace = TYml2Xml.GetAttributeRecursive(node, "Namespace"); if (strNamespace.Length == 0) { return("There is no namespace for " + node.Name); } if (!FGUIAssemblies.Keys.Contains(strNamespace)) { // work around dlls containing several namespaces, eg Ict.Petra.Client.MFinance.Gui contains AR as well string DllName = TAppSettingsManager.ApplicationDirectory + Path.DirectorySeparatorChar + strNamespace; if (!System.IO.File.Exists(DllName + ".dll")) { DllName = DllName.Substring(0, DllName.LastIndexOf(".")); } try { FGUIAssemblies.Add(strNamespace, Assembly.LoadFrom(DllName + ".dll")); } catch (Exception exp) { return("error loading assembly " + strNamespace + ".dll: " + exp.Message); } } Assembly asm = FGUIAssemblies[strNamespace]; string actionClick = TYml2Xml.GetAttribute(node, "ActionClick"); string actionOpenScreen = TYml2Xml.GetAttribute(node, "ActionOpenScreen"); if (actionClick.Contains(".")) { string className = actionClick.Substring(0, actionClick.IndexOf(".")); string methodName = actionClick.Substring(actionClick.IndexOf(".") + 1); System.Type classType = asm.GetType(strNamespace + "." + className); if (classType == null) { return("cannot find class " + strNamespace + "." + className + " for " + node.Name); } MethodInfo method = classType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public); if (method != null) { List <object> parameters = new List <object>(); parameters.Add(AParentWindow); // Check the parameters, if we have such an attribute foreach (ParameterInfo param in method.GetParameters()) { // ignore the first letter, A, eg. in ALedgerNumber if (TYml2Xml.HasAttributeRecursive(node, param.Name.Substring(1))) { Object obj = TYml2Xml.GetAttributeRecursive(node, param.Name.Substring(1)); if (param.ParameterType == typeof(Int32)) { obj = Convert.ToInt32(obj); } else if (param.ParameterType == typeof(Int64)) { obj = Convert.ToInt64(obj); } else if (param.ParameterType == typeof(bool)) { obj = Convert.ToBoolean(obj); } else if (param.ParameterType == typeof(string)) { // leave it as string } else if (param.ParameterType.IsEnum) { obj = Enum.Parse(param.ParameterType, obj.ToString(), true); } else { // to avoid that Icon is set etc, clear obj obj = null; } if (obj != null) { parameters.Add(obj); } } } if (SomeParentDependsOnLedger(node)) { parameters.Add((object)FCurrentLedger); } method.Invoke(null, parameters.ToArray()); } else { return("cannot find method " + className + "." + methodName + " for " + node.Name); } } else if (actionOpenScreen.Length > 0) { string className = actionOpenScreen; System.Object screen = null; System.Type classType = asm.GetType(strNamespace + "." + className); if (classType == null) { return("cannot find class " + strNamespace + "." + className + " for " + node.Name); } // TODO: check if user has permissions for this screen? // needs to be implemented as a static function of the screen, GetRequiredPermission returns the permission that is needed (eg PTNRUSER) // also use something similar as in lstFolderNavigation: CheckAccessPermissionDelegate? // delegate as a static function that is available from everywhere? try { if (OpenNewOrExistingForm != null) { screen = OpenNewOrExistingForm(classType, AParentWindow, out FormWasAlreadyOpened, false); } else { screen = Activator.CreateInstance(classType, new object[] { AParentWindow }); } } catch (System.Reflection.TargetInvocationException E) { TLogging.Log(E.ToString()); String msg = E.Message; if (E.InnerException != null) { msg = E.InnerException.Message; } return(msg); } if (!FormWasAlreadyOpened) { // check for properties and according attributes; this works for the LedgerNumber at the moment foreach (PropertyInfo prop in classType.GetProperties()) { if (TYml2Xml.HasAttributeRecursive(node, prop.Name)) { Object obj = TYml2Xml.GetAttributeRecursive(node, prop.Name); if (prop.PropertyType == typeof(Int32)) { obj = Convert.ToInt32(obj); } else if (prop.PropertyType == typeof(Int64)) { obj = Convert.ToInt64(obj); } else if (prop.PropertyType == typeof(bool)) { obj = Convert.ToBoolean(obj); } else if (prop.PropertyType == typeof(string)) { // leave it as string } else if (prop.PropertyType.IsEnum) { obj = Enum.Parse(prop.PropertyType, obj.ToString(), true); } else { // to avoid that Icon is set etc, clear obj obj = null; } if (obj != null) { prop.SetValue(screen, obj, null); } } if (prop.Name == "LedgerNumber") { if (SomeParentDependsOnLedger(node)) { prop.SetValue(screen, (object)FCurrentLedger, null); } } } MethodInfo method = classType.GetMethod("Show", BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, new Type[] { }, null); if (method != null) { method.Invoke(screen, null); FLastOpenedScreen = (Form)screen; } else { return("cannot find method " + className + ".Show for " + node.Name); } } } else if (actionClick.Length == 0) { return("No action defined for " + node.Name); } else { return("Invalid action " + actionClick + " defined for " + node.Name); } return(""); }
/// <summary> /// verify that all windows open either without error or with proper exception handling /// </summary> private void TestOpenAllWindows() { TLogging.Log(String.Format("Running test 'TestOpenAllWindows' with Culture '{0}'...", Thread.CurrentThread.CurrentCulture.ToString()) + Environment.NewLine); // get all nodes that have an attribute ActionOpenScreen XPathExpression expr = FNavigator.Compile("//*[@ActionOpenScreen]"); XPathNodeIterator iterator = FNavigator.Select(expr); //create counter variables to keep track of number of failures (might do with lists soon...for modules(?)) int NoSysManPermissionCount = 0; int NoOtherPermissionCount = 0; int BadFailures = 0; int TotalWindowsOpened = 0; List <String> notOpened = new List <String>(); List <String> sysManPermissions = new List <String>(); List <String> otherPermissions = new List <String>(); List <String> workingWindows = new List <String>(); while (iterator.MoveNext()) { if (iterator.Current is IHasXmlNode) { XmlNode ActionNode = ((IHasXmlNode)iterator.Current).GetNode(); string className = ActionNode.Attributes["ActionOpenScreen"].Value; if (className == "TFrmBankStatementImport") { // skip this one because it pops up an additional dialog that requires user input continue; } // look at the permissions module the window came from string Module = TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired"); TLstTasks.CurrentLedger = TFrmMainWindowNew.CurrentLedger; // Try to open each screen and log the screens that cannot open try { Assert.AreEqual(String.Empty, TLstTasks.ExecuteAction(ActionNode, null)); if (TLstTasks.LastOpenedScreen != null) { TLstTasks.LastOpenedScreen.Close(); } TotalWindowsOpened++; string WindowAndModule = ActionNode.Name + Environment.NewLine + " Permission Required: " + Module; workingWindows.Add(WindowAndModule); //make sure the user had the permissions to open the windows that it opened if (!UserInfo.GUserInfo.IsInModule(Module) && !Module.Contains("")) { BadFailures++; workingWindows.Add("User did not have permission to access " + Module); } } catch (AssertionException e) { TLogging.Log("Window can't be opened: " + ActionNode.Name + " " + ActionNode.Attributes["ActionOpenScreen"].Value + Environment.NewLine + e.ToString()); // if the failure is a permission failure, just log it but don't fail the test if (Catalog.GetString("Sorry, you don't have enough permissions to do this") == TLstTasks.ExecuteAction(ActionNode, null)) { // make sure user didn't have the necessary permissions to open that window // true means user should have been able to open without error if (UserInfo.GUserInfo.IsInModule(Module)) { BadFailures++; string whyFailed = "User should have been able to open " + ActionNode.Name + " with his " + Module + " permission..."; notOpened.Add(whyFailed); } else { string permissions = TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired"); string WindowAndModule = ActionNode.Name + Environment.NewLine + " Permission Required: " + permissions; if (permissions.Contains("SYSMAN")) { NoSysManPermissionCount++; sysManPermissions.Add(WindowAndModule); } else { NoOtherPermissionCount++; otherPermissions.Add(WindowAndModule); } } } else { BadFailures++; string WindowAndModule = ActionNode.Name + Environment.NewLine + " Permission Required: " + TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired"); notOpened.Add(WindowAndModule); } } // if the exception has to due with a ledger that the user doesn't have permission to access, // make it a permission exception. Else, fail the test. catch (Exception e) { TLogging.Log("Window can't be opened: " + ActionNode.Name + " " + ActionNode.Attributes["ActionOpenScreen"].Value + Environment.NewLine + e.ToString()); string ledgerNumber = TXMLParser.GetAttributeRecursive(ActionNode, "LedgerNumber", true); string ledger = "LEDGER00" + ledgerNumber; if ((ledgerNumber != String.Empty) && !UserInfo.GUserInfo.IsInModule(ledger)) { NoOtherPermissionCount++; string WindowAndModule = ActionNode.Name + Environment.NewLine + " Permission Required: " + TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired") + Environment.NewLine + " " + ledger; otherPermissions.Add(WindowAndModule); } else { BadFailures++; string WindowAndModule = ActionNode.Name + Environment.NewLine + " Permission Required: " + TYml2Xml.GetAttributeRecursive(ActionNode, "PermissionsRequired"); if (ledgerNumber != String.Empty) { WindowAndModule += (Environment.NewLine + " " + ledger); } notOpened.Add(WindowAndModule); } } } } //Give stats about where failures were //feel free to change any formatting, I'm not in love with it right now string notOpenedString = string.Join(Environment.NewLine + " ", notOpened.ToArray()); string sysManPermissionsString = string.Join(Environment.NewLine + " ", sysManPermissions.ToArray()); string otherPermissionsString = string.Join(Environment.NewLine + " ", otherPermissions.ToArray()); string workingWindowsString = string.Join(Environment.NewLine + " ", workingWindows.ToArray()); //print the permissions the user should have TLogging.Log(Environment.NewLine + Environment.NewLine + "User Permissions: " + Environment.NewLine + UserInfo.GUserInfo.GetPermissions()); TLogging.Log(Environment.NewLine + Environment.NewLine + "Statistics: " + Environment.NewLine + "Number of windows opened: " + TotalWindowsOpened + Environment.NewLine + " " + workingWindowsString + Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine + "SYSMAN Permission Exceptions: " + sysManPermissions.Count + Environment.NewLine + " " + sysManPermissionsString + Environment.NewLine + Environment.NewLine + Environment.NewLine + Environment.NewLine + "Other Permission Exceptions: " + otherPermissions.Count + Environment.NewLine + " " + otherPermissionsString + Environment.NewLine + Environment.NewLine + Environment.NewLine + "Windows that should be opened but couldn't: " + notOpened.Count + Environment.NewLine + " " + notOpenedString + Environment.NewLine); //Now the loop is finished so fail if there were exceptions Assert.GreaterOrEqual(TotalWindowsOpened, 190, "Expected to open at least 190 windows"); Assert.GreaterOrEqual(sysManPermissions.Count, 3, "Expected to fail to open at least 3 windows requiring SYSMAN permissions"); Assert.AreEqual(notOpened.Count, 0, "Failed to open at least one window for unexplained reasons"); Assert.AreEqual(otherPermissions.Count, 0, "Unexpected failure to open some windows due to a permissions error, when we should have had sufficient permission"); if (BadFailures > 0) { Assert.Fail(String.Format("General failure to successfully open {0} window(s). Maybe there was an exception??", BadFailures)); } }
private static void ParsePartners(ref PartnerImportExportTDS AMainDS, XmlNode ACurNode, TDBTransaction ATransaction, ref TVerificationResultCollection AVerificationResult) { XmlNode LocalNode = ACurNode; while (LocalNode != null) { if (LocalNode.Name.StartsWith("PartnerGroup")) { ParsePartners(ref AMainDS, LocalNode.FirstChild, ATransaction, ref AVerificationResult); } else if (LocalNode.Name.StartsWith("Partner")) { PPartnerRow PartnerRow = AMainDS.PPartner.NewRowTyped(); Boolean IsExistingPartner = false; if (!TYml2Xml.HasAttributeRecursive(LocalNode, "SiteKey")) { throw new Exception(Catalog.GetString("Missing SiteKey Attribute")); } if (!TYml2Xml.HasAttributeRecursive(LocalNode, "status")) { throw new Exception(Catalog.GetString("Missing status Attribute")); } // get a new partner key if (TYml2Xml.HasAttribute(LocalNode, "PartnerKey")) { PartnerRow.PartnerKey = Convert.ToInt64(TYml2Xml.GetAttribute(LocalNode, "PartnerKey")); if (PPartnerAccess.Exists(PartnerRow.PartnerKey, ATransaction)) { AMainDS.Merge(PPartnerAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.PPartner.DefaultView.RowFilter = String.Format("{0} = '{1}'", PPartnerTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); PartnerRow = (PPartnerRow)AMainDS.PPartner.DefaultView[0].Row; IsExistingPartner = true; } else { AMainDS.PPartner.Rows.Add(PartnerRow); } } else { PartnerRow.PartnerKey = TImportExportYml.NewPartnerKey; TImportExportYml.NewPartnerKey--; } String PartnerClass = TYml2Xml.GetAttributeRecursive(LocalNode, "class"); TLogging.LogAtLevel(TLogging.DEBUGLEVEL_TRACE, PartnerClass + " " + LocalNode.Name + " " + "PartnerKey=" + PartnerRow.PartnerKey ); if (IsExistingPartner && (PartnerClass != PartnerRow.PartnerClass)) { throw new Exception(String.Format("Error: Yml contains Existing Partner {0} with a different partner class {1}!", PartnerRow.PartnerKey, PartnerClass)); } PartnerRow.PartnerClass = PartnerClass; if (PartnerClass == MPartnerConstants.PARTNERCLASS_FAMILY) { PFamilyRow FamilyRow; if (IsExistingPartner) { AMainDS.Merge(PFamilyAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.PFamily.DefaultView.RowFilter = String.Format("{0} = '{1}'", PFamilyTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); FamilyRow = (PFamilyRow)AMainDS.PFamily.DefaultView[0].Row; } else { FamilyRow = AMainDS.PFamily.NewRowTyped(); FamilyRow.PartnerKey = PartnerRow.PartnerKey; PartnerRow.PartnerClass = MPartnerConstants.PARTNERCLASS_FAMILY; AMainDS.PFamily.Rows.Add(FamilyRow); } FamilyRow.FamilyName = TYml2Xml.GetAttributeRecursive(LocalNode, "LastName"); FamilyRow.FirstName = TYml2Xml.GetAttribute(LocalNode, "FirstName"); FamilyRow.Title = TYml2Xml.GetAttribute(LocalNode, "Title"); if (TYml2Xml.HasAttribute(LocalNode, "CreatedAt")) { FamilyRow.DateCreated = Convert.ToDateTime(TYml2Xml.GetAttribute(LocalNode, "CreatedAt")); } PartnerRow.AddresseeTypeCode = MPartnerConstants.PARTNERCLASS_FAMILY; PartnerRow.PartnerShortName = Calculations.DeterminePartnerShortName(FamilyRow.FamilyName, FamilyRow.Title, FamilyRow.FirstName); } if (PartnerClass == MPartnerConstants.PARTNERCLASS_PERSON) { PPersonRow PersonRow; if (IsExistingPartner) { AMainDS.Merge(PPersonAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.PPerson.DefaultView.RowFilter = String.Format("{0} = '{1}'", PPersonTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); PersonRow = (PPersonRow)AMainDS.PPerson.DefaultView[0].Row; } else { PersonRow = AMainDS.PPerson.NewRowTyped(); PersonRow.PartnerKey = PartnerRow.PartnerKey; AMainDS.PPerson.Rows.Add(PersonRow); } PersonRow.FamilyName = TYml2Xml.GetAttributeRecursive(LocalNode, "LastName"); PersonRow.FirstName = TYml2Xml.GetAttribute(LocalNode, "FirstName"); PersonRow.Title = TYml2Xml.GetAttribute(LocalNode, "Title"); if (TYml2Xml.HasAttribute(LocalNode, "CreatedAt")) { PersonRow.DateCreated = Convert.ToDateTime(TYml2Xml.GetAttribute(LocalNode, "CreatedAt")); } // PersonRow.Sp PartnerRow.PartnerShortName = Calculations.DeterminePartnerShortName(PersonRow.FamilyName, PersonRow.Title, PersonRow.FirstName); } else if (PartnerClass == MPartnerConstants.PARTNERCLASS_ORGANISATION) { POrganisationRow OrganisationRow; if (IsExistingPartner) { AMainDS.Merge(POrganisationAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.POrganisation.DefaultView.RowFilter = String.Format("{0} = '{1}'", POrganisationTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); OrganisationRow = (POrganisationRow)AMainDS.POrganisation.DefaultView[0].Row; } else { OrganisationRow = AMainDS.POrganisation.NewRowTyped(); OrganisationRow.PartnerKey = PartnerRow.PartnerKey; AMainDS.POrganisation.Rows.Add(OrganisationRow); } OrganisationRow.OrganisationName = TYml2Xml.GetAttributeRecursive(LocalNode, "Name"); PartnerRow.PartnerShortName = OrganisationRow.OrganisationName; } else if (PartnerClass == MPartnerConstants.PARTNERCLASS_UNIT) { PUnitRow UnitRow; if (IsExistingPartner) { AMainDS.Merge(PUnitAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.PUnit.DefaultView.RowFilter = String.Format("{0} = '{1}'", PUnitTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); UnitRow = (PUnitRow)AMainDS.PUnit.DefaultView[0].Row; } else { UnitRow = AMainDS.PUnit.NewRowTyped(); UnitRow.PartnerKey = PartnerRow.PartnerKey; AMainDS.PUnit.Rows.Add(UnitRow); } UnitRow.UnitTypeCode = TYml2Xml.GetAttributeRecursive(LocalNode, "UnitTypeCode"); UnitRow.UnitName = TYml2Xml.GetAttributeRecursive(LocalNode, "Name"); if (PartnerRow.PartnerKey < -1) { throw new Exception("Invalid Partner Key or No Partner Key - and no proper handling implemented"); // from here... /* * AVerificationResult.Add(new TVerificationResult( * String.Format(Catalog.GetString("Importing Unit {0}"), UnitRow.UnitName), * Catalog.GetString("You need to provide a partner key for the unit"), * TResultSeverity.Resv_Critical)); */ // ...to here: throws Exception in case of a illegal import file? // The above code must have a glitch } if (!TYml2Xml.HasAttribute(LocalNode, "ParentUnitKey")) { throw new Exception( "The currently being processed unit (PartnerKey " + PartnerRow.PartnerKey + ") requires a ParentUnitKey."); } Int64 ParentKey = Convert.ToInt64(TYml2Xml.GetAttributeRecursive(LocalNode, "ParentUnitKey")); UmUnitStructureRow UnitStructureRow = null; if (IsExistingPartner) { AMainDS.Merge(UmUnitStructureAccess.LoadViaPUnitChildUnitKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.UmUnitStructure.DefaultView.RowFilter = String.Format("{0} = '{1}'", UmUnitStructureTable.GetChildUnitKeyDBName(), PartnerRow.PartnerKey); if (AMainDS.UmUnitStructure.DefaultView.Count > 0) { UnitStructureRow = (UmUnitStructureRow)AMainDS.UmUnitStructure.DefaultView[0].Row; } } if (UnitStructureRow == null) { UnitStructureRow = AMainDS.UmUnitStructure.NewRowTyped(); UnitStructureRow.ParentUnitKey = ParentKey; UnitStructureRow.ChildUnitKey = PartnerRow.PartnerKey; AMainDS.UmUnitStructure.Rows.Add(UnitStructureRow); } else { UnitStructureRow.ParentUnitKey = ParentKey; UnitStructureRow.ChildUnitKey = PartnerRow.PartnerKey; } PartnerRow.PartnerShortName = UnitRow.UnitName; } else if (PartnerClass == MPartnerConstants.PARTNERCLASS_BANK) { PBankRow BankRow; if (IsExistingPartner) { AMainDS.Merge(PBankAccess.LoadByPrimaryKey(PartnerRow.PartnerKey, ATransaction)); AMainDS.PBank.DefaultView.RowFilter = String.Format("{0} = '{1}'", PBankTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey); BankRow = (PBankRow)AMainDS.PBank.DefaultView[0].Row; } else { BankRow = AMainDS.PBank.NewRowTyped(); BankRow.PartnerKey = PartnerRow.PartnerKey; AMainDS.PBank.Rows.Add(BankRow); } BankRow.BranchName = TYml2Xml.GetAttribute(LocalNode, "BranchName"); BankRow.BranchCode = TYml2Xml.GetAttribute(LocalNode, "BranchCode"); BankRow.Bic = TYml2Xml.GetAttribute(LocalNode, "BranchBic"); BankRow.EpFormatFile = TYml2Xml.GetAttribute(LocalNode, "EpFormatFile"); if (TYml2Xml.HasAttribute(LocalNode, "CreatedAt")) { BankRow.DateCreated = Convert.ToDateTime(TYml2Xml.GetAttribute(LocalNode, "CreatedAt")); } } else { /* * throw new Exception( * "Unknown Partner Class" + * TYml2Xml.GetAttributeRecursive(LocalNode, "class")); */ // TODO AVerificationResult add failing problem: unknown partner class } PartnerRow.StatusCode = TYml2Xml.GetAttributeRecursive(LocalNode, "status"); // import special types StringCollection SpecialTypes = StringHelper.StrSplit(TYml2Xml.GetAttributeRecursive(LocalNode, "SpecialTypes"), ","); if (IsExistingPartner) { PPartnerTypeAccess.LoadViaPPartner(AMainDS, PartnerRow.PartnerKey, ATransaction); } foreach (string SpecialType in SpecialTypes) { PPartnerTypeRow PartnerTypeRow = null; AMainDS.PPartnerType.DefaultView.RowFilter = String.Format("{0}={1} AND {2}='{3}'", PPartnerTypeTable.GetPartnerKeyDBName(), PartnerRow.PartnerKey, PPartnerTypeTable.GetTypeCodeDBName(), SpecialType ); if (AMainDS.PPartnerType.DefaultView.Count > 0) { PartnerTypeRow = (PPartnerTypeRow)AMainDS.PPartnerType.DefaultView[0].Row; } else { PartnerTypeRow = AMainDS.PPartnerType.NewRowTyped(); PartnerTypeRow.PartnerKey = PartnerRow.PartnerKey; PartnerTypeRow.TypeCode = SpecialType.Trim(); AMainDS.PPartnerType.Rows.Add(PartnerTypeRow); } // Check Partner type exists, or create it bool TypeIsKnown = PTypeAccess.Exists(PartnerTypeRow.TypeCode, ATransaction); if (!TypeIsKnown) { Int32 RowIdx = AMainDS.PType.DefaultView.Find(PartnerTypeRow.TypeCode); // I might have created it a second ago.. if (RowIdx < 0) { PTypeRow TypeRow = AMainDS.PType.NewRowTyped(); TypeRow.TypeCode = PartnerTypeRow.TypeCode; TypeRow.TypeDescription = "Created from YAML import"; AMainDS.PType.Rows.Add(TypeRow); } } } // import subscriptions StringCollection Subscriptions = StringHelper.StrSplit(TYml2Xml.GetAttributeRecursive(LocalNode, "Subscriptions"), ","); foreach (string publicationCode in Subscriptions) { PSubscriptionRow subscription = AMainDS.PSubscription.NewRowTyped(); subscription.PartnerKey = PartnerRow.PartnerKey; subscription.PublicationCode = publicationCode.Trim(); subscription.ReasonSubsGivenCode = "FREE"; AMainDS.PSubscription.Rows.Add(subscription); } // import address XmlNode addressNode = TYml2Xml.GetChild(LocalNode, "Address"); if ((addressNode == null) || (TYml2Xml.GetAttributeRecursive(addressNode, "Street").Length == 0)) { if (!IsExistingPartner) { // add the empty location PPartnerLocationRow partnerlocation = AMainDS.PPartnerLocation.NewRowTyped(true); partnerlocation.SiteKey = 0; partnerlocation.PartnerKey = PartnerRow.PartnerKey; partnerlocation.DateEffective = DateTime.Now; partnerlocation.LocationType = "HOME"; partnerlocation.SendMail = false; partnerlocation.EmailAddress = TYml2Xml.GetAttributeRecursive(addressNode, "Email"); partnerlocation.TelephoneNumber = TYml2Xml.GetAttributeRecursive(addressNode, "Phone"); partnerlocation.MobileNumber = TYml2Xml.GetAttributeRecursive(addressNode, "MobilePhone"); AMainDS.PPartnerLocation.Rows.Add(partnerlocation); } } else { PLocationRow location = AMainDS.PLocation.NewRowTyped(true); location.LocationKey = (AMainDS.PLocation.Rows.Count + 1) * -1; location.SiteKey = 0; if (!TYml2Xml.HasAttributeRecursive(LocalNode, "Country")) { throw new Exception(Catalog.GetString("Missing Country Attribute")); } location.CountryCode = TYml2Xml.GetAttributeRecursive(addressNode, "Country"); location.StreetName = TYml2Xml.GetAttributeRecursive(addressNode, "Street"); location.City = TYml2Xml.GetAttributeRecursive(addressNode, "City"); location.PostalCode = TYml2Xml.GetAttributeRecursive(addressNode, "PostCode"); AMainDS.PLocation.Rows.Add(location); PPartnerLocationRow partnerlocation = AMainDS.PPartnerLocation.NewRowTyped(true); partnerlocation.SiteKey = 0; partnerlocation.LocationKey = location.LocationKey; partnerlocation.PartnerKey = PartnerRow.PartnerKey; partnerlocation.SendMail = true; partnerlocation.DateEffective = DateTime.Now; partnerlocation.LocationType = "HOME"; partnerlocation.EmailAddress = TYml2Xml.GetAttributeRecursive(addressNode, "Email"); partnerlocation.TelephoneNumber = TYml2Xml.GetAttributeRecursive(addressNode, "Phone"); partnerlocation.MobileNumber = TYml2Xml.GetAttributeRecursive(addressNode, "MobilePhone"); AMainDS.PPartnerLocation.Rows.Add(partnerlocation); } // import finance details (bank account number) XmlNode financialDetailsNode = TYml2Xml.GetChild(LocalNode, "FinancialDetails"); ParseFinancialDetails(AMainDS, financialDetailsNode, PartnerRow.PartnerKey, ATransaction); } LocalNode = LocalNode.NextSibling; } }
private static void ParseFinancialDetails(PartnerImportExportTDS AMainDS, XmlNode AFinancialDetailsNode, Int64 APartnerKey, TDBTransaction ATransaction) { if (AFinancialDetailsNode != null) { string BankAccountNumber = TYml2Xml.GetAttributeRecursive(AFinancialDetailsNode, "AccountNumber"); string BankSortCode = TYml2Xml.GetAttributeRecursive(AFinancialDetailsNode, "BankSortCode"); // do we already have a bank with this sort code? Int64 bankPartnerKey = 0; AMainDS.PBank.DefaultView.Sort = PBankTable.GetBranchCodeDBName(); int bankIndex = AMainDS.PBank.DefaultView.Find(BankSortCode); if (bankIndex != -1) { bankPartnerKey = ((PBankRow)AMainDS.PBank.DefaultView[bankIndex].Row).PartnerKey; } if (bankPartnerKey == 0) { string sqlFindBankBySortCode = String.Format("SELECT * FROM PUB_{0} WHERE {1}=?", PBankTable.GetTableDBName(), PBankTable.GetBranchCodeDBName()); OdbcParameter param = new OdbcParameter("branchcode", OdbcType.VarChar); param.Value = BankSortCode; PBankTable bank = new PBankTable(); DBAccess.GDBAccessObj.SelectDT(bank, sqlFindBankBySortCode, ATransaction, new OdbcParameter[] { param }, -1, -1); if (bank.Count > 0) { bankPartnerKey = bank[0].PartnerKey; } } if (bankPartnerKey == 0) { // create a new bank record PBankRow bankRow = AMainDS.PBank.NewRowTyped(true); bankRow.PartnerKey = TImportExportYml.NewPartnerKey; TImportExportYml.NewPartnerKey--; bankRow.BranchCode = BankSortCode; bankRow.BranchName = BankSortCode; AMainDS.PBank.Rows.Add(bankRow); bankPartnerKey = bankRow.PartnerKey; } PBankingDetailsRow bankingDetailsRow = AMainDS.PBankingDetails.NewRowTyped(true); bankingDetailsRow.BankingDetailsKey = (AMainDS.PBankingDetails.Rows.Count + 1) * -1; bankingDetailsRow.BankingType = 0; bankingDetailsRow.BankAccountNumber = BankAccountNumber; bankingDetailsRow.BankKey = bankPartnerKey; AMainDS.PBankingDetails.Rows.Add(bankingDetailsRow); PPartnerBankingDetailsRow partnerBankingDetailsRow = AMainDS.PPartnerBankingDetails.NewRowTyped(true); partnerBankingDetailsRow.PartnerKey = APartnerKey; partnerBankingDetailsRow.BankingDetailsKey = bankingDetailsRow.BankingDetailsKey; AMainDS.PPartnerBankingDetails.Rows.Add(partnerBankingDetailsRow); } }