context: //
  // DO NOT REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  //
  // @Authors:
  //       christiank, timop
  //
  // Copyright 2004-2012 by OM International
  //
  // This file is part of OpenPetra.org.
  //
  // OpenPetra.org is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // OpenPetra.org is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with OpenPetra.org.  If not, see <http://www.gnu.org/licenses/>.
  //
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Collections.Specialized;
  using System.Data;
  
  using Ict.Common;
  using Ict.Common.DB;
  using Ict.Common.Data;
  using Ict.Common.Exceptions;
  using Ict.Petra.Server.MCommon;
  using Ict.Petra.Shared;
  using Ict.Petra.Shared.MPartner;
  using Ict.Petra.Shared.MPartner.Mailroom.Data;
  using Ict.Petra.Server.MPartner.Common;
  using Ict.Petra.Server.MPartner.Mailroom.Data.Access;
  using Ict.Petra.Shared.MPartner.Partner.Data;
  using Ict.Petra.Server.MPartner.Partner.Data.Access;
  using Ict.Petra.Shared.Security;
  using Ict.Petra.Shared.Interfaces.MPartner;
  using Ict.Petra.Server.App.Core.Security;
  
  namespace Ict.Petra.Server.MPartner.Partner.ServerLookups.WebConnectors
  {
      /// <summary>
      /// Performs server-side lookups for the Client in the MPartner.ServerLookups
      /// sub-namespace.
      ///
      /// </summary>
      public class TPartnerServerLookups
      {
          /// <summary>
          /// Gets the ShortName of a Partner.
          ///
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to find the short name for</param>
          /// <param name="APartnerShortName">ShortName for the found Partner ('' if Partner
          /// doesn't exist or PartnerKey is 0)</param>
          /// <param name="APartnerClass">Partner Class of the found Partner (FAMILY if Partner
          /// doesn't exist or PartnerKey is 0)</param>
          /// <param name="AMergedPartners">Set to false if the function should return 'false' if
          /// the Partner' Partner Status is MERGED</param>
          /// <returns>true if Partner was found in DB (except if AMergedPartners is false
          /// and Partner is MERGED) or PartnerKey is 0, otherwise false
          /// </returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean GetPartnerShortName(Int64 APartnerKey,
              out String APartnerShortName,
              out TPartnerClass APartnerClass,
              Boolean AMergedPartners)
          {
              Boolean ReturnValue;
              TStdPartnerStatusCode PartnerStatus;
  
              ReturnValue = MCommonMain.RetrievePartnerShortName(APartnerKey, out APartnerShortName, out APartnerClass, out PartnerStatus);
  
              if (((!AMergedPartners)) && (PartnerStatus == TStdPartnerStatusCode.spscMERGED))
              {
                  ReturnValue = false;
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// Gets the ShortName of a Partner.
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to find the short name for</param>
          /// <param name="APartnerShortName">ShortName for the found Partner</param>
          /// <param name="APartnerClass">Partner Class of the found Partner</param>
          /// <returns></returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean GetPartnerShortName(Int64 APartnerKey, out String APartnerShortName, out TPartnerClass APartnerClass)
          {
              return GetPartnerShortName(APartnerKey, out APartnerShortName, out APartnerClass, true);
          }
  
          /// <summary>
          /// Verifies the existence of a Partner.
          ///
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to find the short name for</param>
          /// <param name="AValidPartnerClasses">Pass in a array of valid PartnerClasses that the
          /// Partner is allowed to have (eg. [PERSON, FAMILY], or an empty array ( [] ).</param>
          /// <param name="APartnerExists">True if the Partner exists in the database or if PartnerKey is 0.</param>
          /// <param name="APartnerShortName">ShortName for the found Partner ('' if Partner
          /// doesn't exist or PartnerKey is 0)</param>
          /// <param name="APartnerClass">Partner Class of the found Partner (FAMILY if Partner
          /// doesn't exist or PartnerKey is 0)</param>
          /// <param name="AIsMergedPartner">true if the Partner' Partner Status is MERGED,
          /// otherwise false</param>
          /// <returns>true if Partner was found in DB (except if AValidPartnerClasses isn't
          /// an empty array and the found Partner isn't of a PartnerClass that is in the
          /// Set) or PartnerKey is 0, otherwise false
          /// </returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean VerifyPartner(Int64 APartnerKey,
              TPartnerClass[] AValidPartnerClasses,
              out bool APartnerExists,
              out String APartnerShortName,
              out TPartnerClass APartnerClass,
              out Boolean AIsMergedPartner)
          {
              Boolean ReturnValue;
              TStdPartnerStatusCode PartnerStatus;
  
              ReturnValue = APartnerExists = MCommonMain.RetrievePartnerShortName(APartnerKey,
                  out APartnerShortName,
                  out APartnerClass,
                  out PartnerStatus);
  //          TLogging.LogAtLevel(7, "TPartnerServerLookups.VerifyPartner: " + Convert.ToInt32(AValidPartnerClasses.Length));
  
              if (AValidPartnerClasses.Length != 0)
              {
                  if (Array.BinarySearch(AValidPartnerClasses, APartnerClass) < 0)
                  {
                      ReturnValue = false;
                  }
              }
  
              if (PartnerStatus == TStdPartnerStatusCode.spscMERGED)
              {
                  AIsMergedPartner = true;
              }
              else
              {
                  AIsMergedPartner = false;
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// Verifies the existence of a Partner and checks if the current user can modify it.
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to find the short name for</param>
          /// <param name="APartnerShortName">ShortName for the found Partner ('' if Partner
          ///  doesn't exist or PartnerKey is 0)</param>
          /// <param name="APartnerClass">Partner Class of the found Partner (FAMILY if Partner
          ///  doesn't exist or PartnerKey is 0)</param>
          /// <param name="AIsMergedPartner">true if the Partner' Partner Status is MERGED,
          ///  otherwise false</param>
          /// <param name="AUserCanAccessPartner">true if the current user has the rights to
          /// access this partner</param>
          /// <returns>true if Partner was found in DB or Partner key = 0, otherwise false</returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean VerifyPartner(Int64 APartnerKey,
              out String APartnerShortName,
              out TPartnerClass APartnerClass,
              out Boolean AIsMergedPartner,
              out Boolean AUserCanAccessPartner)
          {
              APartnerShortName = "";
              APartnerClass = TPartnerClass.FAMILY; // Default. This is not really correct but the best compromise if PartnerKey is 0 or Partner isn't found since we have an enum here.
              AIsMergedPartner = false;
              AUserCanAccessPartner = false;
  
              TDBTransaction ReadTransaction;
              Boolean NewTransaction;
              StringCollection RequiredColumns;
              PPartnerTable PartnerTable;
              Boolean ReturnValue = true;
              TStdPartnerStatusCode PartnerStatus = TStdPartnerStatusCode.spscACTIVE;
  
              // initialise outout Arguments
              if (APartnerKey != 0)
              {
                  // only some fields are needed
                  RequiredColumns = new StringCollection();
                  RequiredColumns.Add(PPartnerTable.GetPartnerShortNameDBName());
                  RequiredColumns.Add(PPartnerTable.GetPartnerClassDBName());
                  RequiredColumns.Add(PPartnerTable.GetStatusCodeDBName());
                  RequiredColumns.Add(PPartnerTable.GetRestrictedDBName());
                  RequiredColumns.Add(PPartnerTable.GetUserIdDBName());
                  RequiredColumns.Add(PPartnerTable.GetGroupIdDBName());
  
                  ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                      TEnforceIsolationLevel.eilMinimum,
                      out NewTransaction);
                  try
                  {
                      PartnerTable = PPartnerAccess.LoadByPrimaryKey(APartnerKey, RequiredColumns, ReadTransaction, null, 0, 0);
                  }
                  finally
                  {
                      if (NewTransaction)
                      {
                          DBAccess.GDBAccessObj.CommitTransaction();
                          TLogging.LogAtLevel(7, "TPartnerServerLookups.VerifyPartner: committed own transaction.");
                      }
                  }
  
                  if (PartnerTable.Rows.Count == 0)
                  {
                      ReturnValue = false;
                  }
                  else
                  {
                      // since we loaded by primary key there must just be one partner row
                      APartnerShortName = PartnerTable[0].PartnerShortName;
                      APartnerClass = SharedTypes.PartnerClassStringToEnum(PartnerTable[0].PartnerClass);
                      PartnerStatus = SharedTypes.StdPartnerStatusCodeStringToEnum(PartnerTable[0].StatusCode);
  
                      // check if user can access partner
                      if (Ict.Petra.Server.MPartner.Common.TSecurity.CanAccessPartner(PartnerTable[0]) == TPartnerAccessLevelEnum.palGranted)
                      {
                          AUserCanAccessPartner = true;
                      }
  
                      // check if partner is merged
                      if (PartnerStatus == TStdPartnerStatusCode.spscMERGED)
                      {
                          AIsMergedPartner = true;
                      }
                      else
                      {
                          AIsMergedPartner = false;
                      }
  
                      ReturnValue = true;
                  }
              }
              else
              {
                  // Return result as valid if Partner Key is 0.
                  ReturnValue = true;
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// Verifies the existence of a Partner
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to find the short name for</param>
          /// <returns>true if Partner was found in DB or Partner key = 0, otherwise false</returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean VerifyPartner(Int64 APartnerKey)
          {
              TDBTransaction ReadTransaction;
              Boolean NewTransaction;
              PPartnerTable PartnerTable;
              Boolean ReturnValue = true;
  
              // initialise outout Arguments
              if (APartnerKey != 0)
              {
                  ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                      TEnforceIsolationLevel.eilMinimum,
                      out NewTransaction);
                  try
                  {
                      PartnerTable = PPartnerAccess.LoadByPrimaryKey(APartnerKey, ReadTransaction);
                  }
                  finally
                  {
                      if (NewTransaction)
                      {
                          DBAccess.GDBAccessObj.CommitTransaction();
                          TLogging.LogAtLevel(7, "TPartnerServerLookups.VerifyPartner: committed own transaction.");
                      }
                  }
  
                  if (PartnerTable.Rows.Count == 0)
                  {
                      ReturnValue = false;
                  }
                  else
                  {
                      ReturnValue = true;
                  }
              }
              else
              {
                  // Return result as valid if Partner Key is 0.
                  ReturnValue = true;
              }
  
              return ReturnValue;
          }
  
          /// <summary>
          /// Verifies the existence of a Partner at a given location
          /// </summary>
          /// <param name="APartnerKey">PartnerKey of Partner to be verified</param>
          /// <param name="ALocationKey">Location Key of Partner to be verified</param>
          /// <param name="AAddressNeitherCurrentNorMailing"></param>
          /// <returns>true if Partner was found in DB at given location, otherwise false</returns>
          [RequireModulePermission("PTNRUSER")]
          public static Boolean VerifyPartnerAtLocation(Int64 APartnerKey,
              TLocationPK ALocationKey, out bool AAddressNeitherCurrentNorMailing)
          {
              AAddressNeitherCurrentNorMailing = true;
  
              TDBTransaction ReadTransaction;
              Boolean NewTransaction;
              PPartnerLocationTable PartnerLocationTable;
              Boolean ReturnValue = true;
  
              ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                  TEnforceIsolationLevel.eilMinimum,
                  out NewTransaction);
              try
              {
                  PartnerLocationTable = PPartnerLocationAccess.LoadByPrimaryKey(APartnerKey,
                      ALocationKey.SiteKey,
                      ALocationKey.LocationKey,
                      ReadTransaction);
              }
              finally
              {
                  if (NewTransaction)
                  {
                      DBAccess.GDBAccessObj.CommitTransaction();
                  }
              }
  
  
gt:             if (PartnerLocationTable.Rows.Count == 0)