/// <summary>
        /// todoComment
        /// </summary>
        private static TSubmitChangesResult PerformSimilarLocationReUseChecks(ref PLocationRow ALocationRow,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            Int64 APartnerKey,
            ref PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            ref PPartnerLocationTable APartnerLocationTable,
            ref TLocationPK[, ] ALocationReUseKeyMapping,
            out Boolean AReUseSimilarLocation,
            ref TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult ReturnValue;
            PPartnerLocationRow PartnerLocationCheckRow;
            DataView ExistingLocationParametersDV;

            PLocationRow ExistingLocationRow;
            Int64 CurrentSiteKey;
            Int64 ExistingSiteKey;
            Int32 CurrentLocationKey;
            Int32 ExistingLocationKey;

            PLocationTable SimilarLocationDT;

//          TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " +
//              AExistingLocationParametersDT.Rows.Count.ToString());
            AReUseSimilarLocation = false;

            if (CheckReUseExistingLocation(ALocationRow, APartnerKey, ref AExistingLocationParametersDT, ASubmitChangesTransaction,
                    out ExistingSiteKey, out ExistingLocationKey))
            {
                // Check if there is a Parameter Row for the LocationKey we are looking at
                ExistingLocationParametersDV = new DataView(AExistingLocationParametersDT,
                    PartnerAddressAggregateTDSSimilarLocationParametersTable.GetSiteKeyDBName() + " = " + ALocationRow.SiteKey.ToString() + " AND " +
                    PartnerAddressAggregateTDSSimilarLocationParametersTable.GetLocationKeyDBName() + " = " + ALocationRow.LocationKey.ToString() +
                    " AND " + PartnerAddressAggregateTDSSimilarLocationParametersTable.GetAnswerProcessedClientSideDBName() + " = false",
                    "",
                    DataViewRowState.CurrentRows);

                if (ExistingLocationParametersDV.Count > 0)
                {
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() + ": found similar Location, decision is needed.");

                    /*
                     * More information is needed (usually via user interaction)
                     * -> stop processing here and return parameters
                     * (usually used for UI interaction)
                     */
                    if (AResponseDS == null)
                    {
//                      TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Creating AResponseDS.");
                        AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    }

//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AExistingLocationParametersDT.Rows.Count: " + AExistingLocationParametersDT.Rows.Count.ToString());
                    AResponseDS.Merge(AExistingLocationParametersDT);
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Merged ExistingLocationParametersDT into AResponseDS.");
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: AResponseDS.Tables[" + MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME +
//                            "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString());
                    return TSubmitChangesResult.scrInfoNeeded;
                }
                else
                {
//                  TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Location " + ALocationRow.LocationKey.ToString() +
//                      ": found similar Location and this one (" + ExistingLocationKey.ToString() + ") should be used instead of creating a new one!");

                    /*
                     * Location with the same data already exists and it should be
                     * re-used instead of creating a new one!
                     */

                    // Keep a mapping of the initially submitted LocationKey to the newly assigned one
                    ALocationReUseKeyMapping = new TLocationPK[ALocationReUseKeyMapping.GetLength(0) + 1, 2];
                    ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 0] = new TLocationPK(ALocationRow.SiteKey,
                        (int)ALocationRow.LocationKey);
                    ALocationReUseKeyMapping[(ALocationReUseKeyMapping.GetLength(0)) - 1, 1] = new TLocationPK(ExistingSiteKey, ExistingLocationKey);
                    AReUseSimilarLocation = true;

                    if (!AExistingLocationParametersDT[0].AnswerProcessedServerSide)
                    {
                        AExistingLocationParametersDT[0].AnswerProcessedServerSide = true;

                        // Preserve Key of current Location
                        CurrentSiteKey = ALocationRow.SiteKey;
                        CurrentLocationKey = (int)ALocationRow.LocationKey;

                        /*
                         * Make sure that the Partner hasn't already got a PartnerLocation with
                         * the same Key (neither in memory nor in the DB)
                         */
//                      TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: Finding PartnerLocation Row in APartnerLocationTable with LocationKey " + ALocationRow.LocationKey.ToString());
                        PartnerLocationCheckRow =
                            (PPartnerLocationRow)APartnerLocationTable.Rows.Find(new object[] { APartnerKey, ALocationRow.SiteKey,
                                                                                                ALocationRow.LocationKey });

                        if (PartnerLocationCheckRow != null)
                        {
                            /*
                             * Checks in Memory: look for Current (ie. unchanged, new or edited)
                             * rows first whether they are the Location that is about to being
                             * reused. Secondly, check if there is a deleted Location with the same
                             * LocationKey that is about to being reused; only if this is not the
                             * case:
                             * Check in the DB whether the Partner hasn't got the Location
                             * with the same LocationKey that is about to being reuse.
                             */
                            if ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() +
                                     " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " +
                                     PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "",
                                     DataViewRowState.CurrentRows).Length != 0)
                                || ((APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() +
                                         " AND " +
                                         PPartnerLocationTable.GetSiteKeyDBName() + " = " + ExistingSiteKey.ToString() + " AND " +
                                         PPartnerLocationTable.GetLocationKeyDBName() + " = " + ExistingLocationKey.ToString(), "",
                                         DataViewRowState.Deleted).Length == 0)
                                    && (PPartnerLocationAccess.Exists(APartnerKey, ExistingSiteKey, ExistingLocationKey,
                                            ASubmitChangesTransaction))))
                            {
                                AVerificationResult.Add(new TVerificationResult("[Partner Address Save]", "Partner " + APartnerKey.ToString() +
                                        " already has a " + "record linked with Location " + ExistingLocationKey.ToString() + Environment.NewLine +
                                        "Unable to save.", "Duplicate Address Entered", "", TResultSeverity.Resv_Critical));
                                ReturnValue = TSubmitChangesResult.scrError;
                                return ReturnValue;
                            }
                            else
                            {
//                              TLogging.LogAtLevel(9, "PerformSimilarLocationReUseChecks: LocationKey: " + ExistingLocationKey.ToString() + " will later get assigned to PPartnerLocation.");
                            }
                        }
                        else
                        {
                            throw new EOPAppException(
                                "PerformSimilarLocationReUseChecks: PartnerLocationCheckRow with SiteKey " + ALocationRow.SiteKey.ToString() +
                                " and LocationKey " +
                                ALocationRow.LocationKey.ToString() + " not found!");
                        }

                        /*
                         * Copy all fields from the existing Location to the current Location
                         */
                        SimilarLocationDT = PLocationAccess.LoadByPrimaryKey(ExistingSiteKey, ExistingLocationKey, null, ASubmitChangesTransaction);

                        if (SimilarLocationDT.Rows.Count != 0)
                        {
                            ExistingLocationRow = (PLocationRow)SimilarLocationDT.Rows[0];

                            ALocationRow.ItemArray = ExistingLocationRow.ItemArray;

                            /*
                             * NOTE: The SiteKey and LocationKey are re-assigned to the ones of the
                             * current Location. This is done to have the current SiteKey and
                             * LocationKey preserved throughout the whole process of working with the
                             * Locations. The SiteKey and LocationKey are exchanged with the ones of
                             * the existing Location before the DataRow gets sent back to the Client!
                             */
                            ALocationRow.SiteKey = CurrentSiteKey;
                            ALocationRow.LocationKey = CurrentLocationKey;
//                          TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() +
//                                ": data got replaced with data from the existing Location (" + ExistingLocationKey.ToString() + ")!");
                        }
                        else
                        {
                            throw new EOPAppException(
                                "Couldn''t find existing Similar Location with SiteKey " + ALocationRow.SiteKey.ToString() + " and LocationKey " +
                                ALocationRow.LocationKey.ToString() + '!');
                        }
                    }
                }
            }
            else
            {
//              TLogging.LogAtLevel(9, "CheckReUseExistingLocation: Location " + ALocationRow.LocationKey.ToString() +
//                  ": Location does not exist yet (or an existing Location should not be re-used) -> will get saved later.");

                /*
                 * No similar Location exists, or an existing similar Location should
                 * not be re-used: Save this Location
                 * -> will get saved later in call to SubmitChanges
                 */
            }

            return TSubmitChangesResult.scrOK;
        }
        /// <summary>
        /// Prepare the address changes. Check for the rules regarding locations
        /// </summary>
        public static TSubmitChangesResult PrepareChanges(PartnerEditTDS AInspectDS,
            Int64 APartnerKey,
            String APartnerClass,
            TDBTransaction ASubmitChangesTransaction,
            ref PartnerAddressAggregateTDS AResponseDS,
            out TVerificationResultCollection AVerificationResult)
        {
            PartnerAddressAggregateTDSSimilarLocationParametersTable ExistingLocationParametersDT;
            PartnerAddressAggregateTDSChangePromotionParametersTable ChangeLocationParametersDT;
            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AddressAddedOrChangedPromotionParametersDT;

            AVerificationResult = null;

            if (AInspectDS == null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: AInspectDS = nil!");
                return TSubmitChangesResult.scrNothingToBeSaved;
            }

            AVerificationResult = new TVerificationResultCollection();
            TLocationPK[, ] SimilarLocationReUseKeyMapping = new TLocationPK[1, 2];

            if (AInspectDS.PLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: PLocation Rows: " + AInspectDS.PLocation.Rows.Count.ToString());
            }

            if (AInspectDS.PPartnerLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: PPartnerLocation Rows: " + AInspectDS.PPartnerLocation.Rows.Count.ToString());
            }

            if (TLogging.DL >= 8)
            {
                DebugLocationsBeforeSaving(AInspectDS);
            }

            // Check if Parameter Tables are passed in
            CheckParameterTables(AResponseDS,
                out ExistingLocationParametersDT,
                out ChangeLocationParametersDT,
                out AddressAddedOrChangedPromotionParametersDT);

            if (AInspectDS.PLocation != null)
            {
                TSubmitChangesResult result = ProcessLocationChanges(
                    AInspectDS.PLocation,
                    AInspectDS.PPartnerLocation,
                    ref AResponseDS,
                    ASubmitChangesTransaction,
                    APartnerKey,
                    ref ExistingLocationParametersDT,
                    ref SimilarLocationReUseKeyMapping,
                    ref AddressAddedOrChangedPromotionParametersDT,
                    ref ChangeLocationParametersDT,
                    ref AVerificationResult);

                if (result != TSubmitChangesResult.scrOK)
                {
                    // Stop processing here, we need more information!

                    return result;
                }
            }

            if (AInspectDS.PPartnerLocation != null)
            {
                TSubmitChangesResult result = ProcessPartnerLocationChanges(
                    AInspectDS.PPartnerLocation,
                    ref AResponseDS,
                    ASubmitChangesTransaction,
                    APartnerKey,
                    APartnerClass,
                    ref SimilarLocationReUseKeyMapping,
                    ref ExistingLocationParametersDT,
                    ref AddressAddedOrChangedPromotionParametersDT,
                    ref ChangeLocationParametersDT,
                    ref AVerificationResult);

                if (result != TSubmitChangesResult.scrOK)
                {
                    // Stop processing here, we need more information!

                    return result;
                }
            }

            /*
             * Actual saving of data
             */
            if (AInspectDS.PLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: Length(SimilarLocationReUseKeyMapping): " + Convert.ToInt16(SimilarLocationReUseKeyMapping.GetLength(0)).ToString());

                if ((SimilarLocationReUseKeyMapping.GetLength(0) - 1) > 0)
                {
                    for (Int16 LocationReUseCounter = 1;
                         LocationReUseCounter <= SimilarLocationReUseKeyMapping.GetLength(0) - 1;
                         LocationReUseCounter += 1)
                    {
/* if DEBUGMODE
 *                      if (TLogging.DL >= 9)
 *                      {
 *                          TLogging.Log("LocationReUseCounter: " + LocationReUseCounter.ToString());
 *                          TLogging.Log(
 *                              "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() +
 *                              ", 0].LocationKey: " +
 *                              SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString());
 *                          TLogging.Log(
 *                              "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() +
 *                              ", 1].LocationKey: " +
 *                              SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey.ToString());
 *                      }
 */
                        PLocationRow ReUsedLocationDR =
                            (PLocationRow)AInspectDS.PLocation.Rows.Find(
                                new System.Object[] { SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].SiteKey,
                                                      SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey });

                        if (ReUsedLocationDR != null)
                        {
                            // Overwrite the originally submitted Key with the one that
                            // replaces it. This is needed to have the correct Key on
                            // the Client side!
                            ReUsedLocationDR.SiteKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].SiteKey;
                            ReUsedLocationDR.LocationKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey;

                            // Make the DataRow 'unchanged' so that it doesn't get saved in the
                            // SubmitChanges call for PLocation!
                            ReUsedLocationDR.AcceptChanges();

                            // Remember that the row should not be submitted lateron
                            // NotToBeSubmittedLocationRows.Add(ReUsedLocationDR);
                        }
                        else
                        {
                            throw new EOPAppException("ReUsedLocationDR for SiteKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter,
                                                               0].SiteKey.ToString() + " and LocationKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString() + " could not be found!");
                        }
                    }
                }
            }

            if (AInspectDS.PPartnerLocation != null)
            {
//              TLogging.LogAtLevel(9, "SubmitChanges: Length(SimilarLocationReUseKeyMapping): " + Convert.ToInt16(SimilarLocationReUseKeyMapping.GetLength(0)).ToString());

                if ((SimilarLocationReUseKeyMapping.GetLength(0) - 1) > 0)
                {
                    for (Int16 LocationReUseCounter = 1;
                         LocationReUseCounter <= SimilarLocationReUseKeyMapping.GetLength(0) - 1;
                         LocationReUseCounter += 1)
                    {
//                      TLogging.LogAtLevel(9, "LocationReUseCounter: " + LocationReUseCounter.ToString());
//                      TLogging.LogAtLevel(9, "SubmitChanges: LocationReUseKeyMapping[" + LocationReUseCounter.ToString() + ", 0].LocationKey: " +
//                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString());
                        PPartnerLocationRow ReUsedPartnerLocationDR = (PPartnerLocationRow)AInspectDS.PPartnerLocation.Rows.Find(
                            new System.Object[] { APartnerKey, SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].SiteKey,
                                                  SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey });

                        if (ReUsedPartnerLocationDR != null)
                        {
                            // Overwrite the originally submitted Key with the one that
                            // replaces it. This is needed to have the correct Key on
                            // the Client side!
                            ReUsedPartnerLocationDR.SiteKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].SiteKey;
                            ReUsedPartnerLocationDR.LocationKey = SimilarLocationReUseKeyMapping[LocationReUseCounter, 1].LocationKey;
                        }
                        else
                        {
                            throw new EOPAppException("ReUsedPartnerLocationDR for SiteKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter,
                                                               0].SiteKey.ToString() + " and LocationKey " +
                                SimilarLocationReUseKeyMapping[LocationReUseCounter, 0].LocationKey.ToString() + " could not be found!");
                        }
                    }
                }
            }

            return TSubmitChangesResult.scrOK;
        }
        /// <summary>
        /// Allows adding of a new Location of a FAMILY Partner to all PERSONS of that
        /// FAMILY.
        ///
        /// @comment Must only be called for Partners of Partner Class FAMILY - the
        /// function does no checks on that and will fail for other Partner Classes!
        /// </summary>
        /// <returns>void</returns>
        private static TSubmitChangesResult PerformLocationFamilyMemberPropagationChecks(PPartnerLocationRow APartnerLocationRow,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            Int64 APartnerKey,
            String APartnerClass,
            ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedPromotionDT,
            ref PPartnerLocationTable APartnerLocationTable,
            PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            TLocationPK[, ] ALocationReUseKeyMapping,
            out Boolean APerformPropagation,
            ref TVerificationResultCollection AVerificationResult)
        {
//          TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks for LocationKey: " + APartnerLocationRow.LocationKey.ToString() +
//                    "; AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString());

            APerformPropagation = false;
            TLocationPK SubmittedLocationPK = DetermineReplacedLocationPK(APartnerLocationRow, ALocationReUseKeyMapping);
            TLocationPK LocationPK = DetermineReplacedLocationPK(APartnerLocationRow, AExistingLocationParametersDT);

            if (CheckFamilyMemberPropagation(APartnerLocationRow, APartnerKey, APartnerClass, ref AAddressAddedPromotionDT, LocationPK,
                    ASubmitChangesTransaction))
            {
                // Check if there is a Parameter Row for the LocationKey we are looking at
                DataView PropagateLocationParametersDV = new DataView(AAddressAddedPromotionDT,
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " + LocationPK.SiteKey.ToString() +
                    " AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " +
                    LocationPK.LocationKey.ToString() +
                    " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationAddedDBName() + " = true AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = false",
                    "",
                    DataViewRowState.CurrentRows);

                if (PropagateLocationParametersDV.Count > 0)
                {
//                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Location " + APartnerLocationRow.LocationKey.ToString() + ": found Family Members, decision on propagation is needed.");

                    /*
                     * More information is needed (usually via user interaction)
                     * -> stop processing here and return parameters
                     * (usually used for UI interaction)
                     */
                    if (AResponseDS == null)
                    {
//                      TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Creating AResponseDS.");
                        AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    }

//                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString());
                    AResponseDS.Merge(AAddressAddedPromotionDT);
//                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Merged AAddressAddedPromotionDT into AResponseDS.");
//                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: PerformLocationFamilyMemberPropagationChecks: AResponseDS.Tables[" +
//                            MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME + "].Rows.Count: " +
//                            AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString());
                    return TSubmitChangesResult.scrInfoNeeded;
                }
                else
                {
//                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Location " + APartnerLocationRow.LocationKey.ToString() + ": found Family Members and new Location should be propagated to them!");

                    /*
                     * Family Members were found and the new Location should be added to all
                     * of them!
                     */
                    APerformPropagation = true;

                    // Load all Persons of the Family
                    PPersonTable FamilyPersonsDT = PPersonAccess.LoadViaPFamily(APartnerKey, ASubmitChangesTransaction);

                    // Find PPartnerLocation row of the Family that we should process
                    PPartnerLocationRow FamilyPartnerLocationRow = (PPartnerLocationRow)APartnerLocationTable.Rows.Find(
                        new System.Object[] { APartnerKey, APartnerLocationRow.SiteKey,
                                              APartnerLocationRow.LocationKey });

                    if (FamilyPartnerLocationRow != null)
                    {
                        for (int Counter = 0; Counter <= FamilyPersonsDT.Rows.Count - 1; Counter += 1)
                        {
                            PPersonRow ProcessedPersonRow = FamilyPersonsDT[Counter];
//                          TLogging.LogAtLevel(9,  "PerformLocationFamilyMemberPropagationChecks: Person  " + ProcessedPersonRow.PartnerKey.ToString() + ": checking...");

                            // Check if Person doesn't already have the Location
                            if (!PPartnerLocationAccess.Exists(ProcessedPersonRow.PartnerKey, SubmittedLocationPK.SiteKey,
                                    SubmittedLocationPK.LocationKey, ASubmitChangesTransaction))
                            {
                                /*
                                 * PartnerLocation records for family members are added to APartnerLocationTable for easier data handling and
                                 * will be removed again after SubmitChanges of whole dataset but before returning to client as otherwise
                                 * they would confusingly show up on client side.
                                 */

                                // Make sure record is not added more than once to APartnerLocationTable (in case it is not yet in database).
                                if (APartnerLocationTable.Rows.Find(new System.Object[] { ProcessedPersonRow.PartnerKey, SubmittedLocationPK.SiteKey,
                                                                                          SubmittedLocationPK.LocationKey }) == null)
                                {
                                    //                              TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Person  " + ProcessedPersonRow.PartnerKey.ToString() +
                                    //                                  ": adding Location " + SubmittedLocationPK.LocationKey.ToString() + "...");

                                    // Add a copy of the PartnerLocation data to the Person
                                    PPartnerLocationRow AddPartnerLocationRow = APartnerLocationTable.NewRowTyped(false);
                                    AddPartnerLocationRow.ItemArray = DataUtilities.DestinationSaveItemArray(AddPartnerLocationRow,
                                        FamilyPartnerLocationRow);
                                    AddPartnerLocationRow.PartnerKey = ProcessedPersonRow.PartnerKey;
                                    AddPartnerLocationRow.SiteKey = SubmittedLocationPK.SiteKey;
                                    AddPartnerLocationRow.LocationKey = SubmittedLocationPK.LocationKey;
                                    APartnerLocationTable.Rows.Add(AddPartnerLocationRow);

                                    /*
                                     * If this Person has an PartnerLocation with LocationKey 0 (this
                                     * means that this was the only PartnerLocation so far), delete the
                                     * PartnerLocation with LocationKey 0.
                                     */
                                    if (PPartnerLocationAccess.Exists(ProcessedPersonRow.PartnerKey, SubmittedLocationPK.SiteKey, 0,
                                            ASubmitChangesTransaction))
                                    {
                                        //                                  TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Person  " + ProcessedPersonRow.PartnerKey.ToString() + ": had Location 0 assigned, deleting it.");
                                        PPartnerLocationAccess.DeleteByPrimaryKey(ProcessedPersonRow.PartnerKey,
                                            APartnerLocationRow.SiteKey,
                                            0,
                                            ASubmitChangesTransaction);
                                    }
                                }
                            }
                            else
                            {
//                              TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Person  " + ProcessedPersonRow.PartnerKey.ToString() +
//                                      ": already has Location " + SubmittedLocationPK.LocationKey.ToString() + " assigned.");
                            }
                        }
                    }
                    else
                    {
                        throw new EOPAppException(
                            "TPPartnerAddressAggregate.PerformLocationFamilyMemberPropagationChecks: PPartnerLocation record for Family is missing");
                    }
                }
            }
            else
            {
//              TLogging.LogAtLevel(9, "PerformLocationFamilyMemberPropagationChecks: Location " + SubmittedLocationPK.LocationKey.ToString() +
//                  ": Family either has no Family Members, or no propagation of the new Location is wanted. New Location will therefore only be added to the FAMILY.");

                /*
                 * Family either has no Family Members, or it has Members, but the decision
                 * was made that the new PartnerLocation should not be added to the Family
                 * Members.
                 * The new Location will therefore only be added to the FAMILY.
                 */
            }

            return TSubmitChangesResult.scrOK;
        }
        /// <summary>
        /// Check each Location DataRow before calling SubmitChanges
        /// to enforce Business Rules:
        /// - Added or changed Location: check for a similar Location record
        /// - if no similar Location record exists, save this Location record
        /// - if a similar Location record exists: allow choosing whether the
        ///    existing one should be used, or this Location record should be saved
        /// - Changed Location: don't save Location record if the data is actually
        ///     the same than before
        /// - Deleted Location: delete Location only if no other PartnerLocation
        ///      is referencing it
        /// - Deleted Location: remove references from any Extracts
        /// </summary>
        private static TSubmitChangesResult ProcessLocationChanges(
            PLocationTable ALocationTable,
            PPartnerLocationTable APartnerLocationTable,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            Int64 APartnerKey,
            ref PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            ref TLocationPK[, ] ASimilarLocationReUseKeyMapping,
            ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedOrChangedPromotionParametersDT,
            ref PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT,
            ref TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult Result = TSubmitChangesResult.scrOK;
            TSubmitChangesResult TmpResult;

            for (Int16 LocationCounter = 0; LocationCounter < ALocationTable.Rows.Count; LocationCounter++)
            {
                if ((ALocationTable.Rows[LocationCounter].RowState == DataRowState.Added)
                    || (ALocationTable.Rows[LocationCounter].RowState == DataRowState.Modified))
                {
                    if (ALocationTable[LocationCounter].LocationKey == 0)
                    {
                        throw new Exception("TPPartnerAddress.ProcessLocationChanges: must not add or modify the empty location");
                    }
                }

                if (ALocationTable.Rows[LocationCounter].RowState == DataRowState.Deleted)
                {
                    if (Convert.ToInt32(ALocationTable[LocationCounter][PLocationTable.GetLocationKeyDBName(),
                                                                        DataRowVersion.Original]) == 0)
                    {
                        throw new Exception("TPPartnerAddress.ProcessLocationChanges: must not delete the empty location");
                    }
                }

                if (ALocationTable.Rows[LocationCounter].RowState == DataRowState.Added)
                {
                    bool ReUseSimilarLocation = false;

                    // Check for reuse of a similar location in the DB
                    PLocationRow TmpRow = ALocationTable[LocationCounter];
                    TmpResult = PerformSimilarLocationReUseChecks(
                        ref TmpRow,
                        ref AResponseDS,
                        ASubmitChangesTransaction,
                        APartnerKey,
                        ref AExistingLocationParametersDT,
                        ref APartnerLocationTable,
                        ref ASimilarLocationReUseKeyMapping,
                        out ReUseSimilarLocation,
                        ref AVerificationResult);
//                  TLogging.LogAtLevel(8, "SubmitChanges: TmpRow.LocationKey after PerformSimilarLocationReUseChecks (1): " + TmpRow.LocationKey.ToString());

                    if (TmpResult != TSubmitChangesResult.scrOK)
                    {
                        // Stop processing here - we need a decision whether to re-use
                        // an existing Location or not (or the user tried to re-use a
                        // Location that is already used by this Partner, which is a
                        // user error)
                        return TmpResult;
                    }
                } // DataRowState.Added
                else if (ALocationTable.Rows[LocationCounter].RowState == DataRowState.Modified)
                {
                    if (CheckHasLocationChanged(ALocationTable[LocationCounter]))
                    {
                        bool ReUseSimilarLocation = false;

                        // Check for reuse of a similar location in the DB
                        PLocationRow TmpRow = ALocationTable[LocationCounter];
                        TmpResult = PerformSimilarLocationReUseChecks(ref TmpRow,
                            ref AResponseDS,
                            ASubmitChangesTransaction,
                            APartnerKey,
                            ref AExistingLocationParametersDT,
                            ref APartnerLocationTable,
                            ref ASimilarLocationReUseKeyMapping,
                            out ReUseSimilarLocation,
                            ref AVerificationResult);

//                      TLogging.LogAtLevel(9, "SubmitChanges: TmpRow.LocationKey after PerformSimilarLocationReUseChecks (2): " + TmpRow.LocationKey.ToString());

                        if (TmpResult != TSubmitChangesResult.scrOK)
                        {
                            // Stop processing here - we need a decision whether to re-use
                            // an existing Location or not (or the user tried to re-use a
                            // Location that is already used by this Partner, which is a
                            // user error)
                            return TmpResult;
                        }

                        if (!ReUseSimilarLocation)
                        {
                            // No similar Location exists, or an existing similar Location
                            // should not be reused
                            if (CheckHasPartnerLocationOtherPartnerReferences(ALocationTable[LocationCounter], APartnerKey,
                                    ASubmitChangesTransaction))
                            {
//                              TLogging.LogAtLevel(9, "SubmitChanges: Location " + ALocationTable[LocationCounter].LocationKey.ToString() + ": is used by other Partners as well.");

                                bool CreateLocationFlag;
                                TLocationPK OriginalLocationKey;

                                TmpResult =
                                    PerformLocationChangeChecks(ALocationTable[LocationCounter],
                                        APartnerKey,
                                        ref AResponseDS,
                                        ASubmitChangesTransaction,
                                        ref AAddressAddedOrChangedPromotionParametersDT,
                                        ref AChangeLocationParametersDT,
                                        ref APartnerLocationTable,
                                        ref AVerificationResult,
                                        out CreateLocationFlag,
                                        out OriginalLocationKey);

                                if (TmpResult != TSubmitChangesResult.scrOK)
                                {
                                    Result = TmpResult;

                                    if (Result == TSubmitChangesResult.scrError)
                                    {
                                        return Result;
                                    }
                                }

                                if (CreateLocationFlag)
                                {
                                    ModifyExistingLocationParameters(ALocationTable[LocationCounter],
                                        OriginalLocationKey,
                                        ref AExistingLocationParametersDT);

                                    // Make this location's DataRow undmodified because it should not be submitted to the database
                                    ALocationTable.Rows[LocationCounter].AcceptChanges();
                                    LocationCounter--;
                                }
                            } // if CheckHasPartnerLocationOtherPartnerReferences ... then
                        }
                    } // if CheckHasLocationChanged ... then
                    else
                    {
//                      TLogging.LogAtLevel(9, "Location " + ALocationTable[LocationCounter].LocationKey.ToString() + ": data has NOT changed -> will not be saved.");

                        // remove this location because it should not be submitted to the database
                        ALocationTable.Rows.RemoveAt(LocationCounter);
                        LocationCounter--;
                    }
                } // DataRowState.Modified
                else if (ALocationTable.Rows[LocationCounter].RowState == DataRowState.Deleted)
                {
//                  TLogging.LogAtLevel(9, "SubmitChanges: Location " + ALocationTable[LocationCounter]
//                      [PLocationTable.GetLocationKeyDBName(), DataRowVersion.Original].ToString() + ": has been marked for deletion.");

                    // Handle deletion of Location row: delete it only if no other PartnerLocation is referencing it
                    if (CheckHasPartnerLocationOtherPartnerReferences(ALocationTable[LocationCounter], APartnerKey, ASubmitChangesTransaction))
                    {
//                      TLogging.LogAtLevel(9,  TLogging.Log("SubmitChanges: Location " +
//                          ALocationTable[LocationCounter][PLocationTable.GetLocationKeyDBName(), DataRowVersion.Original].ToString() +
//                          ": has been marked for deletion and is used by others, so it won''t get deleted.");

                        // remove this location because it should not be submitted to the database
                        ALocationTable.Rows.RemoveAt(LocationCounter);
                        LocationCounter--;
                    }
                    else
                    {
//                      TLogging.LogAtLevel(9, "SubmitChanges: Location " + ALocationTable[LocationCounter][PLocationTable.GetLocationKeyDBName(),
//                          DataRowVersion.Original].ToString() + ": has been marked for deletion and will get deleted.");

                        // Any Extract in Petra that references this Location must no longer
                        // reference this Location since it will get deleted
                        RemoveLocationFromExtracts(ALocationTable[LocationCounter], ASubmitChangesTransaction);
                    }
                } // if LocationTable.Rows[LocationCounter].RowState = DataRowState.Deleted
                else if (ALocationTable.Rows[LocationCounter].RowState != DataRowState.Unchanged)
                {
                    throw new ArgumentException(
                        "SubmitChanges can only deal with Locations of DataRowState Added, Modified or Deleted, but not with " +
                        (Enum.GetName(typeof(DataRowState), ALocationTable.Rows[LocationCounter].RowState)));
                }
            }

            return Result;
        }
        /// <summary>
        ///  Check each PartnerLocation DataRow before calling SubmitChanges
        ///  to enforce Business Rules:
        ///  - Added PartnerLocation:
        ///  - if working with a PartnerLocation of a FAMILY:
        ///  - Added PartnerLocation: if working with a Location of a FAMILY: allow
        ///  choosing whether this PartnerLocation should be added to all PERSONs
        ///  in the FAMILY
        ///  - make sure that Location 0 is no longer mapped to this Partner.
        ///  - Modified Location:
        ///  - if working with a PartnerLocation of a FAMILY:
        ///  - check whether other Partners are referencing it, and if so,
        ///  allow choosing which of the Partners (or none or all) should be
        ///  affected by the change
        ///  - if the value in the DateGoodUntil column has changed, silently
        ///  update it for all PERSONs of a FAMILY that have the same LocationKey.
        ///  - Deleted PartnerLocation: check whether this is the last
        ///  PartnerLocation that is left for this Partner. If this is the case,
        ///  don't delete the PartnerLocation, but set it's LocationKey to 0.
        /// </summary>
        private static TSubmitChangesResult ProcessPartnerLocationChanges(
            PPartnerLocationTable PartnerLocationTable,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            Int64 APartnerKey,
            String APartnerClass,
            ref TLocationPK[, ] ASimilarLocationReUseKeyMapping,
            ref PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedOrChangedPromotionParametersDT,
            ref PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT,
            ref TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult Result = TSubmitChangesResult.scrOK;
            TSubmitChangesResult TmpResult;

            for (Int16 PartnerLocationCounter = 0; PartnerLocationCounter <= PartnerLocationTable.Rows.Count - 1; PartnerLocationCounter += 1)
            {
                switch (PartnerLocationTable.Rows[PartnerLocationCounter].RowState)
                {
                    case DataRowState.Added:

                        if (PartnerLocationTable[PartnerLocationCounter].LocationKey != 0)
                        {
                            /*
                             * PartnerLocation of a FAMILY: Family Members promotion
                             */
                            if (APartnerClass == SharedTypes.PartnerClassEnumToString(TPartnerClass.FAMILY))
                            {
                                bool PerformPropagation = false;

                                TmpResult = PerformLocationFamilyMemberPropagationChecks(
                                    PartnerLocationTable[PartnerLocationCounter],
                                    ref AResponseDS,
                                    ASubmitChangesTransaction,
                                    APartnerKey,
                                    APartnerClass,
                                    ref AAddressAddedOrChangedPromotionParametersDT,
                                    ref PartnerLocationTable,
                                    AExistingLocationParametersDT,
                                    ASimilarLocationReUseKeyMapping,
                                    out PerformPropagation,
                                    ref AVerificationResult);

                                if (TmpResult != TSubmitChangesResult.scrOK)
                                {
                                    Result = TmpResult;

                                    if (TmpResult == TSubmitChangesResult.scrError)
                                    {
                                        return TmpResult;
                                    }
                                }

                                if (PerformPropagation)
                                {
                                    ModifyAddressAddedOrChangedParameters(PartnerLocationTable[PartnerLocationCounter],
                                        ref AAddressAddedOrChangedPromotionParametersDT);
                                }
                            }

                            /*
                             * Since a new Location has been added, we need to make sure that
                             * Location 0 is no longer mapped to this Partner!
                             */
                            MakeSureLocation0IsNotPresent(APartnerKey,
                                PartnerLocationTable[PartnerLocationCounter].SiteKey,
                                PartnerLocationTable,
                                ASubmitChangesTransaction);
                        }
                        else
                        {
                            MakeSureLocation0SavingIsAllowed(PartnerLocationTable[PartnerLocationCounter],
                                APartnerKey,
                                ASubmitChangesTransaction);
                        }

                        break;

                    case DataRowState.Modified:

                        /*
                         * PartnerLocation of a FAMILY: Family Members promotion
                         */
                        if (APartnerClass == SharedTypes.PartnerClassEnumToString(TPartnerClass.FAMILY))
                        {
                            /*
                             * If the value in the DateGoodUntil column has changed, silently
                             * update it for all PERSONs of this FAMILY that have the same
                             * LocationKey.
                             */
                            if (TSaveConvert.ObjectToDate(PartnerLocationTable[PartnerLocationCounter][PPartnerLocationTable.
                                                                                                       GetDateGoodUntilDBName(),
                                                                                                       DataRowVersion.Original]) !=
                                TSaveConvert.ObjectToDate(PartnerLocationTable[PartnerLocationCounter][PPartnerLocationTable.
                                                                                                       GetDateGoodUntilDBName(),
                                                                                                       DataRowVersion.Current]))
                            {
//                              TLogging.LogAtLevel(8, "SubmitChanges: PartnerLocation of a FAMILY: DateGoodUntil has changed -> promoting change to FAMILY members...");

                                PromoteToFamilyMembersDateGoodUntilChange(APartnerKey, PartnerLocationTable[PartnerLocationCounter],
                                    ASubmitChangesTransaction);
                            }
                        }

                        break;

                    case DataRowState.Deleted:

                        /*
                         * PPartnerLocation must not get deleted if it is the last one of the
                         * Partner, but must get mapped to Location 0 instead!
                         */

                        // Make sure that Location 0 can never get deleted!
                        if (Convert.ToInt32(PartnerLocationTable[PartnerLocationCounter][PPartnerLocationTable.GetLocationKeyDBName(),
                                                                                         DataRowVersion.Original]) != 0)
                        {
                            // Some other Location than Location 0 is about to be deleted!
                            // Check in the in-memory PartnerLocation Table first...
                            DataRow[] ChangePartnerLocationKeyRows = PartnerLocationTable.Select(
                                PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() + " AND " +
                                PPartnerLocationTable.GetLocationKeyDBName() + " <> " +
                                PartnerLocationTable[PartnerLocationCounter][PPartnerLocationTable.GetLocationKeyDBName(),
                                                                             DataRowVersion.Original].ToString(), "",
                                DataViewRowState.CurrentRows);

                            if (ChangePartnerLocationKeyRows.Length == 0)
                            {
                                // No PPartnerLocation that is not deleted is left in
                                // PartnerLocationTable > now check for deleted ones
                                DataView DeletedPartnerLocationsDV = new DataView(PartnerLocationTable, "", "", DataViewRowState.Deleted);
                                int[] DeletedPartnerLocationKeys = new int[DeletedPartnerLocationsDV.Count];

                                for (Int16 DeletedPartnerLocationsCounter = 0;
                                     DeletedPartnerLocationsCounter <= DeletedPartnerLocationsDV.Count - 1;
                                     DeletedPartnerLocationsCounter += 1)
                                {
                                    DeletedPartnerLocationKeys[DeletedPartnerLocationsCounter] =
                                        Convert.ToInt32(DeletedPartnerLocationsDV[DeletedPartnerLocationsCounter].Row[PPartnerLocationTable.
                                                                                                                      GetLocationKeyDBName(),
                                                                                                                      DataRowVersion.Original
                                            ]);
                                }

                                // now check in the DB as well
                                if (!CheckHasPartnerOtherPartnerLocations(DeletedPartnerLocationKeys, APartnerKey, ASubmitChangesTransaction))
                                {
                                    // 'Undelete' DataRow and make it point to Location 0
                                    // (dummy Location) > will get submitted lateron!
                                    PartnerLocationTable[PartnerLocationCounter].RejectChanges();
                                    PartnerLocationTable[PartnerLocationCounter].LocationKey = 0;
//                                  TLogging.LogAtLevel(8, "SubmitChanges: PPartnerLocation " +
//                                      PartnerLocationTable[PartnerLocationCounter][PPartnerLocationTable.GetLocationKeyDBName(),
//                                      DataRowVersion.Original].ToString() + ": was last PartnerLocation, so its LocationKey got set to 0 (will be submitted lateron)!");
                                }
                            }
                            else
                            {
                                // There is at least one PPartnerLocation that is not deleted
                                // left in PartnerLocationTable, so the current PPartnerLocation
                                // can't be the last one > nothing to do.
                            }
                        }
                        else
                        {
                            DataRow[] ChangePartnerLocationKeyRows = PartnerLocationTable.Select(
                                PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() + " AND " +
                                PPartnerLocationTable.GetLocationKeyDBName() + " = 0 ", "", DataViewRowState.CurrentRows);
//                          TLogging.LogAtLevel(8, "SubmitChanges: ChangePartnerLocationKeyRows Length: " + Convert.ToInt16(ChangePartnerLocationKeyRows.Length).ToString());

                            if (ChangePartnerLocationKeyRows.Length != 0)
                            {
                                // remove this location because it should not be submitted to the database
                                PartnerLocationTable.Rows.RemoveAt(PartnerLocationCounter);
                                PartnerLocationCounter--;

//                              TLogging.LogAtLevel(8, "SubmitChanges: Extra Location 0 row won''t be submitted lateron");
                            }
                        }

                        break;

                    case DataRowState.Unchanged:
                        break;

                    default:
                        throw new ArgumentException(
                        "SubmitChanges can only deal with PartnerLocations of DataRowState Added, Modified or Deleted, but not with " +
                        (Enum.GetName(typeof(DataRowState), PartnerLocationTable.Rows[PartnerLocationCounter].RowState)));
                }
            }

            return Result;
        }
        /// <summary>
        /// check the location change; validate and take other required action
        /// eg. change the location of family members, promote address changes
        /// </summary>
        /// <param name="ALocationRow"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="AResponseDS"></param>
        /// <param name="ASubmitChangesTransaction"></param>
        /// <param name="AAddressAddedPromotionDT"></param>
        /// <param name="AChangeLocationParametersDT"></param>
        /// <param name="APartnerLocationTable"></param>
        /// <param name="AVerificationResult"></param>
        /// <param name="ACreateLocation"></param>
        /// <param name="AOriginalLocationKey"></param>
        /// <returns></returns>
        private static TSubmitChangesResult PerformLocationChangeChecks(PLocationRow ALocationRow,
            Int64 APartnerKey,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedPromotionDT,
            ref PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT,
            ref PPartnerLocationTable APartnerLocationTable,
            ref TVerificationResultCollection AVerificationResult,
            out Boolean ACreateLocation,
            out TLocationPK AOriginalLocationKey)
        {
            TSubmitChangesResult ReturnValue;
            DataView PropagateLocationParametersDV;
            DataView PropagateLocationParametersDV2;
            Boolean UpdateLocation;

            Int64[] CreateLocationOtherPartnerKeys;
            PartnerAddressAggregateTDSChangePromotionParametersTable ChangePromotionParametersDT;
            PLocationTable NewLocationTable;
            PLocationRow NewLocationRowSaved;
            Int32 NewLocationLocationKey;
            PPartnerLocationRow PartnerLocationRowForChangedLocation;

            DataSet PartnerLocationModifyDS;
            int Counter;
            Int64 OldLocationKey;
            OdbcParameter[] ParametersArray;
            String OtherPartnerKeys = "";

            AOriginalLocationKey = null;
//          TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString());

            if (CheckLocationChange(ALocationRow, APartnerKey, ref AAddressAddedPromotionDT, ASubmitChangesTransaction, out UpdateLocation,
                    out ACreateLocation, out CreateLocationOtherPartnerKeys, out ChangePromotionParametersDT))
            {
                // Check if there is a Parameter Row for the LocationKey we are looking at
                PropagateLocationParametersDV = new DataView(AAddressAddedPromotionDT,
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " + ALocationRow.SiteKey.ToString() +
                    " AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " +
                    ALocationRow.LocationKey.ToString() +
                    " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationChangeDBName() + " = true AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = false",
                    "",
                    DataViewRowState.CurrentRows);

                if (PropagateLocationParametersDV.Count > 0)
                {
//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() +
//                          ": Location has been changed, decision on propagation is needed.");

                    /*
                     * More information is needed (usually via user interaction)
                     * -> stop processing here and return parameters
                     * (usually used for UI interaction)
                     */
                    if (AResponseDS == null)
                    {
//                      TLogging.LogAtLevel(9, TLogging.Log("PerformLocationChangeChecks: Creating AResponseDS.");
                        AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    }

//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressAddedPromotionDT.Rows.Count.ToString());
                    AResponseDS.Merge(AAddressAddedPromotionDT);
//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Merged AAddressAddedPromotionDT into AResponseDS.");
                    AResponseDS.Merge(ChangePromotionParametersDT);
//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Merged ChangePromotionParametersDT into AResponseDS.");
//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: AResponseDS.Tables[" + MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME +
//                      "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME].Rows.Count.ToString());
                    return TSubmitChangesResult.scrInfoNeeded;
                }
                else
                {
//                  TLogging.LogAtLevel(9, "PerformLocationChangeChecks: User made his/her choice regarding Location Change promotion; now processing...");

                    /*
                     * User made his/her choice regarding Location Change promotion; now process it
                     */
                    if (ACreateLocation)
                    {
                        OldLocationKey = ALocationRow.LocationKey;
                        AOriginalLocationKey = new TLocationPK(
                            Convert.ToInt64(ALocationRow[PLocationTable.GetSiteKeyDBName(),
                                                         DataRowVersion.Original]),
                            Convert.ToInt32(ALocationRow[PLocationTable.GetLocationKeyDBName(),
                                                         DataRowVersion.Original]));

                        // ALocationRow.LocationKey;
//                      TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + AOriginalLocationKey.LocationKey.ToString() + ": should be created.");

                        /*
                         * Create and save NEW Location that holds the same data than the changed
                         * Location.
                         */
                        NewLocationTable = new PLocationTable();
                        NewLocationRowSaved = NewLocationTable.NewRowTyped(false);
                        NewLocationRowSaved.ItemArray = DataUtilities.DestinationSaveItemArray(NewLocationRowSaved, ALocationRow);
                        NewLocationRowSaved.LocationKey = -1;
                        NewLocationTable.Rows.Add(NewLocationRowSaved);

                        // Submit the NEW Location to the DB
                        PLocationAccess.SubmitChanges(NewLocationTable, ASubmitChangesTransaction);

                        // The DB gives us a LocationKey from a Sequence. Remember this one.
                        NewLocationLocationKey = (Int32)NewLocationRowSaved.LocationKey;
//                      TLogging.LogAtLevel(9, "PerformLocationChangeChecks: New Location created! Its Location Key is: " + NewLocationLocationKey.ToString());

                        // Add the new row to the LocationTable that is beeing processed as well
                        // NewLocationCurrentTableRow := (ALocationRow.Table as PLocationTable).NewRowTyped(false);
                        // NewLocationCurrentTableRow.ItemArray := NewLocationRowSaved.ItemArray;
                        // ALocationRow.Table.Rows.Add(NewLocationCurrentTableRow);
                        // Make the row unchanged so that it isn't picked up as a 'new Address'
                        // and that it doesn't get saved later. Will be sent back to the Partner
                        // Edit screen lateron.
                        // NewLocationCurrentTableRow.AcceptChanges;

                        /*
                         * Update the reference from the changed Location to the new Location in
                         * the Partner's PartnerLocation DataTable. This will be saved later in
                         * the call to SubmitChanges in the main loop of the SubmitData function.
                         */
                        PartnerLocationRowForChangedLocation =
                            (PPartnerLocationRow)APartnerLocationTable.Rows.Find(new object[] { APartnerKey, ALocationRow.SiteKey,
                                                                                                ALocationRow.LocationKey });
                        PartnerLocationRowForChangedLocation.LocationKey = NewLocationLocationKey;

                        // Now delete the changed Location so that it doesn't get saved!
                        // ALocationRow.Delete;
                        // ALocationRow.AcceptChanges;
                        // Overwrite the Location that should be replaced with the data of the new Location
                        ALocationRow.ItemArray = NewLocationRowSaved.ItemArray;
                        PropagateLocationParametersDV2 = new DataView(AAddressAddedPromotionDT,
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " +
                            NewLocationRowSaved.SiteKey.ToString() + " AND " +
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " +
                            OldLocationKey.ToString() +
                            " AND " + PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationChangeDBName() + " = true AND " +
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = true",
                            "",
                            DataViewRowState.CurrentRows);
                        ((PartnerAddressAggregateTDSAddressAddedOrChangedPromotionRow)(PropagateLocationParametersDV2[0].Row)).LocationKey =
                            ALocationRow.LocationKey;

                        if (CreateLocationOtherPartnerKeys.Length > 0)
                        {
//                          TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Created Location " + NewLocationLocationKey.ToString() +
//                              ": should be assigned to " + Convert.ToInt32(CreateLocationOtherPartnerKeys.Length).ToString() + " Partners...");

                            // Build list of PartnerKeys for IN (x,y) clause in the SQL statement
                            for (Counter = 0; Counter <= CreateLocationOtherPartnerKeys.Length - 1; Counter += 1)
                            {
                                OtherPartnerKeys = OtherPartnerKeys + CreateLocationOtherPartnerKeys[Counter].ToString() + ',';
                            }

                            // remove last ','
                            OtherPartnerKeys = OtherPartnerKeys.Substring(0, OtherPartnerKeys.Length - 1);

                            // Load data for all the other selected Partners that reference
                            // the PartnerLocation
                            PartnerLocationModifyDS = new DataSet();
                            PartnerLocationModifyDS.Tables.Add(new PPartnerLocationTable());
                            ParametersArray = new OdbcParameter[2];
                            ParametersArray[0] = new OdbcParameter("", OdbcType.Decimal, 10);
                            ParametersArray[0].Value = (System.Object)(NewLocationRowSaved.SiteKey);
                            ParametersArray[1] = new OdbcParameter("", OdbcType.Int);
                            ParametersArray[1].Value = (System.Object)(AOriginalLocationKey.LocationKey);
                            PartnerLocationModifyDS = DBAccess.GDBAccessObj.Select(PartnerLocationModifyDS,
                                "SELECT * " + "FROM PUB_" + PPartnerLocationTable.GetTableDBName() + ' ' + "WHERE " +
                                PPartnerLocationTable.GetPartnerKeyDBName() + " IN (" + OtherPartnerKeys + ") " + "AND " +
                                PPartnerLocationTable.GetSiteKeyDBName() + " = ? " + "AND " + PPartnerLocationTable.GetLocationKeyDBName() + " = ?",
                                PPartnerLocationTable.GetTableName(),
                                ASubmitChangesTransaction,
                                ParametersArray);

                            // Change the LocationKey for every one of those PartnerLocation
                            // DataRows to point to the NEW Location
                            for (Counter = 0; Counter <= CreateLocationOtherPartnerKeys.Length - 1; Counter += 1)
                            {
                                ((PPartnerLocationTable)PartnerLocationModifyDS.Tables[0])[Counter].LocationKey = NewLocationLocationKey;
                            }

                            // Submit the changes to those PartnerLocations to the DB
                            PPartnerLocationAccess.SubmitChanges((PPartnerLocationTable)PartnerLocationModifyDS.Tables[0],
                                ASubmitChangesTransaction);
                        }
                        else
                        {
//                          TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Created Location " + NewLocationLocationKey.ToString() + ": should not be assigned to any other Partners...");

                            /*
                             * Don't need to do anything here - the just created Location got already
                             * assigned to the Partner we are currently working with.
                             */
                        }
                    }
                    else if (UpdateLocation)
                    {
//                      TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() +
//                              ": should simply get updated; therefore the Locations of ALL Partners will be changed...");

                        /*
                         * Don't need to do anything here - the changed Location will be saved
                         * in the call to SubmitChanges in the main loop of the SubmitData function.
                         */
                    }
                }

                ReturnValue = TSubmitChangesResult.scrOK;
            }
            else
            {
                TLogging.LogAtLevel(9, "PerformLocationChangeChecks: Location " + ALocationRow.LocationKey.ToString() +
                    ": User cancelled the selection - stopping the whole saving process!");

                /*
                 * User cancelled the selection - stop the whole saving process!
                 */
                AVerificationResult.Add(new TVerificationResult("Location Change Promotion: Information",
                        "No changes were saved because the Location Change Promotion dialog was cancelled by the user.", "Saving cancelled by user",
                        "",
                        TResultSeverity.Resv_Noncritical));
                ReturnValue = TSubmitChangesResult.scrError;
            }

            return ReturnValue;
        }
        /// <summary>
        /// todoComment
        /// </summary>
        /// <param name="AInspectDS"></param>
        /// <param name="AExistingLocationParametersDT"></param>
        /// <param name="AChangeLocationParametersDT"></param>
        /// <param name="AAddressAddedOrChangedPromotionParametersDT"></param>
        private static void CheckParameterTables(PartnerAddressAggregateTDS AInspectDS,
            out PartnerAddressAggregateTDSSimilarLocationParametersTable AExistingLocationParametersDT,
            out PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT,
            out PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressAddedOrChangedPromotionParametersDT)
        {
            if (AInspectDS != null)
            {
                if (AInspectDS.Tables.Contains(MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME))
                {
                    if (AInspectDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME] is
                        PartnerAddressAggregateTDSSimilarLocationParametersTable)
                    {
                        AExistingLocationParametersDT =
                            (PartnerAddressAggregateTDSSimilarLocationParametersTable)AInspectDS.Tables[MPartnerConstants.
                                                                                                        EXISTINGLOCATIONPARAMETERS_TABLENAME];

/* if DEBUGMODE
 *                      if (TLogging.DL >= 9)
 *                      {
 *                          TLogging.Log(
 *                              "CheckParameterTables: Passed in ParameterTable ''" + MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME +
 *                              "''; Rows.Count: " + AExistingLocationParametersDT.Rows.Count.ToString());
 *                      }
 *                      if (TLogging.DL >= 8)
 *                      {
 *                          for (Int16 TmpRowCounter = 0; TmpRowCounter <= AExistingLocationParametersDT.Rows.Count - 1; TmpRowCounter += 1)
 *                          {
 *                              TLogging.Log(
 *                                  "CheckParameterTables: AExistingLocationParametersDT: Row[" + TmpRowCounter.ToString() + "]: PLocationKey: " +
 *                                  AExistingLocationParametersDT[TmpRowCounter][PartnerAddressAggregateTDSSimilarLocationParametersTable.
 *                                                                               GetLocationKeyDBName(),
 *                                                                               DataRowVersion.Original].ToString() + "; PSiteKey: " +
 *                                  AExistingLocationParametersDT[TmpRowCounter][PartnerAddressAggregateTDSSimilarLocationParametersTable.
 *                                                                               GetSiteKeyDBName(),
 *                                                                               DataRowVersion.Original].ToString() + "; RowState: " +
 *                                  (Enum.GetName(typeof(DataRowState), AExistingLocationParametersDT.Rows[TmpRowCounter].RowState)));
 *                          }
 *                      }
 */
                    }
                    else
                    {
                        throw new EOPAppException("Expected Typed DataTable, received normal DataTable");
                    }
                }
                else
                {
                    AExistingLocationParametersDT = new PartnerAddressAggregateTDSSimilarLocationParametersTable(
                        MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME);
                }

                if (AInspectDS.Tables.Contains(MPartnerConstants.ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME))
                {
                    if (AInspectDS.Tables[MPartnerConstants.ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME] is
                        PartnerAddressAggregateTDSChangePromotionParametersTable)
                    {
                        AChangeLocationParametersDT =
                            (PartnerAddressAggregateTDSChangePromotionParametersTable)AInspectDS.Tables[MPartnerConstants.
                                                                                                        ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME];
//                      TLogging.LogAtLevel(9, "CheckParameterTables: Passed in ParameterTable ''" + MPartnerConstants.ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME +
//                          "''; Rows.Count: " + AChangeLocationParametersDT.Rows.Count.ToString());
                    }
                    else
                    {
                        throw new EOPAppException("Expected Typed DataTable, received normal DataTable");
                    }
                }
                else
                {
                    AChangeLocationParametersDT = new PartnerAddressAggregateTDSChangePromotionParametersTable(
                        MPartnerConstants.ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME);
                }

                if (AInspectDS.Tables.Contains(MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME))
                {
                    if (AInspectDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME] is
                        PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable)
                    {
                        AAddressAddedOrChangedPromotionParametersDT =
                            (PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable)AInspectDS.Tables
                            [MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME];
//                      TLogging.LogAtLevel(9, "CheckParameterTables: Passed in ParameterTable ''" + MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME +
//                                "''; Rows.Count: " + AAddressAddedOrChangedPromotionParametersDT.Rows.Count.ToString());
                    }
                    else
                    {
                        throw new EOPAppException("Expected Typed DataTable, received normal DataTable");
                    }
                }
                else
                {
                    AAddressAddedOrChangedPromotionParametersDT = new PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable(
                        MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME);
                }
            }
            else
            {
//              TLogging.LogAtLevel(9, "CheckParameterTables: Passed in ParameterDataSet is nil.");
                AExistingLocationParametersDT = new PartnerAddressAggregateTDSSimilarLocationParametersTable(
                    MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME);
                AChangeLocationParametersDT = new PartnerAddressAggregateTDSChangePromotionParametersTable(
                    MPartnerConstants.ADDRESSCHANGEPROMOTIONPARAMETERS_TABLENAME);
                AAddressAddedOrChangedPromotionParametersDT = new PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable(
                    MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME);
            }
        }
Esempio n. 8
0
        private TSubmitChangesResult SubmitChangesAddresses(ref PartnerEditTDS AInspectDS,
            TDBTransaction ASubmitChangesTransaction,
            ref PartnerAddressAggregateTDS AResponseDS,
            out TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult SubmissionResult;

            AVerificationResult = null;
//          TLogging.LogAtLevel(7, "TPartnerEditUIConnector.SubmitChangesAddresses: Instance hash is " + this.GetHashCode().ToString());

            if (AInspectDS != null)
            {
                SubmissionResult =
                    TPPartnerAddressAggregate.PrepareChanges(
                        AInspectDS,
                        FPartnerKey,
                        SharedTypes.PartnerClassEnumToString(FPartnerClass),
                        ASubmitChangesTransaction,
                        ref AResponseDS,
                        out AVerificationResult);

                /*
                 * Business Rule: Ensure that the DateModified of the Partner record is
                 * changed to today's date if a new PPartnerLocation is added.
                 */
                if (SubmissionResult == TSubmitChangesResult.scrOK)
                {
                    if (AInspectDS.PPartnerLocation != null)
                    {
                        DataView AddedPartnerLocationsDV = new DataView(AInspectDS.PPartnerLocation, "", "", DataViewRowState.Added);

                        if (AddedPartnerLocationsDV.Count > 0)
                        {
                            // New PPartnerLocation exists
                            TLogging.LogAtLevel(7,
                                "TPartnerEditUIConnector.SubmitChangesAddresses: New PPartnerLocation or changed PPartnerLocation exists.");

                            if (AInspectDS.PPartner != null)
                            {
                                if (AInspectDS.PPartner.Rows.Count > 0)
                                {
                                    // AInspectDS contains a PPartner DataRow > simply update the
                                    // DateModified there (strictly speaking this should not be necessary
                                    // because the DataStore should do that anyway when the PPartner
                                    // record is saved, but just to be sure it happens...)
                                    AInspectDS.PPartner[0].DateModified = DateTime.Today;
//                                  TLogging.LogAtLevel(7,  "TPartnerEditUIConnector.SubmitChangesAddresses: updated PPartner's DateModified to today (PPartner record was present).");
                                }
                            }
                            else
                            {
                                // AInspectDS doesn't contain a PPartner DataRow: load that PPartner
                                // record, change DateModified and save the PPartner record.
                                // must use AddedPartnerLocationsDV because AInspectDS.PPartnerLocation[0] could be a deleted row; see bug 759
                                PPartnerTable PartnerDT = PPartnerAccess.LoadByPrimaryKey(
                                    ((PPartnerLocationRow)(AddedPartnerLocationsDV[0].Row)).PartnerKey,
                                    ASubmitChangesTransaction);
                                PartnerDT[0].DateModified = DateTime.Today;
                                AInspectDS.Merge(PartnerDT);
//                              TLogging.LogAtLevel(7, "TPartnerEditUIConnector.SubmitChangesAddresses: updated PPartner's DateModified to today (PPartner record wasn't present).");
                            }
                        }
                    }
                }

                if (SubmissionResult == TSubmitChangesResult.scrError)
                {
//                  TLogging.LogAtLevel(9, Messages.BuildMessageFromVerificationResult("TPartnerEditUIConnector.SubmitChangesAddresses AVerificationResult: ", AVerificationResult));
                }
            }
            else
            {
                TLogging.LogAtLevel(8, "TPartnerEditUIConnector.SubmitChangesAddresses:AInspectDS = nil!");
                SubmissionResult = TSubmitChangesResult.scrNothingToBeSaved;
            }

            return SubmissionResult;
        }
Esempio n. 9
0
        /// <summary>
        /// Saves data from the Partner Edit Screen (contained in a Typed DataSet).
        ///
        /// All DataTables contained in the Typed DataSet are inspected for added,
        /// changed or deleted rows by submitting them to the DataStore.
        ///
        /// </summary>
        /// <param name="AInspectDS">Typed DataSet that needs to contain known DataTables</param>
        /// <param name="AResponseDS">DataSet containing data to be used on the Client side
        /// (eg. for displaying Address Change dialogs with data in it)</param>
        /// <param name="AVerificationResult">Nil if all verifications are OK and all DB calls
        /// succeded, otherwise filled with 1..n TVerificationResult objects
        /// (can also contain DB call exceptions)</param>
        /// <returns>true if all verifications are OK and all DB calls succeeded, false if
        /// any verification or DB call failed
        /// </returns>
        public TSubmitChangesResult SubmitChanges(ref PartnerEditTDS AInspectDS,
            ref DataSet AResponseDS,
            out TVerificationResultCollection AVerificationResult)
        {
            TDBTransaction SubmitChangesTransaction = null;
            TSubmitChangesResult SubmissionResult = TSubmitChangesResult.scrError;
            PartnerAddressAggregateTDS TmpResponseDS = null;
            DataSet ResponseDS = AResponseDS;
            PartnerEditTDS InspectDS = AInspectDS;

            AVerificationResult = null;

            if (AInspectDS != null)
            {
                #region Work with AResponseDS if present

                if (AResponseDS != null)
                {
//                  TLogging.LogAtLevel(8, "AResponseDS.Tables.Count: " + AResponseDS.Tables.Count.ToString());

                    if (AResponseDS.Tables.Contains(MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME))
                    {
//                      TLogging.LogAtLevel(8, MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME + " Type: " +
//                          AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].GetType().ToString() + "; Rows.Count: " +
//                          AResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString());
                    }

                    // AResponseDS is present: make a local copy and set AResponseDS to nil
                    TmpResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    TmpResponseDS.Merge(AResponseDS);
                    AResponseDS = null;
                    ResponseDS = AResponseDS;
//                  TLogging.LogAtLevel(8, "TmpResponseDS.Tables.Count: " + TmpResponseDS.Tables.Count.ToString());

                    if (TmpResponseDS.Tables.Contains(MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME))
                    {
//                      TLogging.LogAtLevel(8, MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME + " Type: " +
//                          TmpResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].GetType().ToString() +
//                          "; Rows.Count: " + TmpResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count.ToString());
                    }
                }

                #endregion

                TVerificationResultCollection SingleVerificationResultCollection;
                AVerificationResult = new TVerificationResultCollection();
                TVerificationResultCollection VerificationResult = AVerificationResult;

                FSubmissionDS = AInspectDS;

                DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction,
                    ref SubmissionResult,
                    delegate
                    {
                        PrepareBankingDetailsForSaving(ref InspectDS, ref VerificationResult, SubmitChangesTransaction);

                        if (!TVerificationHelper.IsNullOrOnlyNonCritical(VerificationResult))
                        {
                            SubmissionResult = TSubmitChangesResult.scrError;

                            return;
                        }

                        try
                        {
                            if (SubmitChangesOther(ref FSubmissionDS, SubmitChangesTransaction, out SingleVerificationResultCollection))
                            {
                                SubmissionResult = TSubmitChangesResult.scrOK;
                            }
                            else
                            {
                                SubmissionResult = TSubmitChangesResult.scrError;
                            }

                            VerificationResult.AddCollection(SingleVerificationResultCollection);

                            if (SubmissionResult != TSubmitChangesResult.scrError)
                            {
                                TSubmitChangesResult SubmitChangesAddressResult = SubmitChangesAddresses(ref FSubmissionDS,
                                    SubmitChangesTransaction,
                                    ref TmpResponseDS,
                                    out SingleVerificationResultCollection);

                                if (SubmitChangesAddressResult == TSubmitChangesResult.scrOK)
                                {
                                    // don't need to do anything here; SubmissionResult is set already
                                }
                                else
                                {
                                    SubmissionResult = SubmitChangesAddressResult;

                                    if (SubmitChangesAddressResult == TSubmitChangesResult.scrInfoNeeded)
                                    {
                                        ResponseDS = (DataSet)TmpResponseDS;
                                        //                              TLogging.LogAtLevel(8, "ResponseDS.Tables.Count: " + ResponseDS.Tables.Count.ToString());

                                        if (ResponseDS.Tables.Contains(MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME))
                                        {
                                            //                                  TLogging.LogAtLevel(7, MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME + " Type: " +
                                            //                                      ResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].GetType().ToString());
                                            if (TLogging.DL >= 8)
                                            {
                                                if (ResponseDS.Tables[MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME].Rows.Count > 0)
                                                {
                                                    Console.WriteLine(
                                                        MPartnerConstants.EXISTINGLOCATIONPARAMETERS_TABLENAME + "[0].AnswerProcessedClientSide: " +
                                                        ((PartnerAddressAggregateTDSSimilarLocationParametersTable)(ResponseDS.Tables[
                                                                                                                        MPartnerConstants.
                                                                                                                        EXISTINGLOCATIONPARAMETERS_TABLENAME
                                                                                                                    ]))[0].AnswerProcessedClientSide.
                                                        ToString());
                                                }
                                            }
                                        }

                                        if (ResponseDS.Tables.Contains(MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME))
                                        {
                                            //                                  TLogging.LogAtLevel(8,  MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME + " Type: " +
                                            //                                      ResponseDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME].GetType().ToString());
                                            if (TLogging.DL >= 8)
                                            {
                                                if (ResponseDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME].Rows.Count > 0)
                                                {
                                                    Console.WriteLine(
                                                        MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME +
                                                        "[0].AnswerProcessedClientSide: " +
                                                        ((PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable)(ResponseDS.Tables[
                                                                                                                             MPartnerConstants
                                                                                                                             .
                                                                                                                             ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME
                                                                                                                         ]))[0].
                                                        AnswerProcessedClientSide.
                                                        ToString());
                                                }
                                            }
                                        }
                                    }
                                }

                                VerificationResult.AddCollection(SingleVerificationResultCollection);
                            }

                            if (SubmissionResult == TSubmitChangesResult.scrOK)
                            {
                                // all tables in the dataset will be stored.
                                // there are exceptions: for example cascading delete of foundations, change of unique key of family id
                                // those tables need to have run AcceptChanges
                                PartnerEditTDSAccess.SubmitChanges(InspectDS);
                            }

                            if (SubmissionResult == TSubmitChangesResult.scrOK)
                            {
                                // Save data from the Personnel Data part (needs to be done here towards the end of saving
                                // as p_person record needs to be saved earlier in the process and is referenced from data saved here.
                                if (SubmitChangesPersonnelData(ref FSubmissionDS, SubmitChangesTransaction, out SingleVerificationResultCollection))
                                {
                                    SubmissionResult = TSubmitChangesResult.scrOK;
                                }
                                else
                                {
                                    SubmissionResult = TSubmitChangesResult.scrError;
                                    VerificationResult.AddCollection(SingleVerificationResultCollection);
                                }
                            }

                            // now remove temporary records from PPartnerLocation that were used for propagation of addresses to family members
                            // (otherwise those address records for family members would show up on client where they are not needed)
                            if (SubmissionResult == TSubmitChangesResult.scrOK)
                            {
                                if (InspectDS.Tables.Contains(PPartnerLocationTable.GetTableName()))
                                {
                                    Int64 ThisPartnerKey = FPartnerKey;

                                    if (ThisPartnerKey == 0)
                                    {
                                        // if FPartnerKey is not set then check if there is just one partner record in the dataset and take that key
                                        if (InspectDS.Tables.Contains(PPartnerTable.GetTableName())
                                            && (InspectDS.PPartner.Count == 1))
                                        {
                                            ThisPartnerKey = ((PPartnerRow)InspectDS.PPartner.Rows[0]).PartnerKey;

                                            if (ThisPartnerKey == 0)
                                            {
                                                // only bring up this message if there is just one partner record in the dataset
                                                Console.WriteLine("FPartnerKey in TPartnerEditUIConnector should not be 0!");
                                            }
                                        }
                                    }

                                    if (ThisPartnerKey != 0)
                                    {
                                        DataView OtherPartnerLocationsDV =
                                            new DataView(InspectDS.PPartnerLocation, PPartnerLocationTable.GetPartnerKeyDBName() + " <> " +
                                                ThisPartnerKey.ToString(), "", DataViewRowState.CurrentRows);
                                        int NumberOfOtherPartnerLocationRows = OtherPartnerLocationsDV.Count;

                                        for (int Counter = NumberOfOtherPartnerLocationRows - 1; Counter >= 0; Counter--)
                                        {
                                            OtherPartnerLocationsDV[Counter].Row.Delete();
                                        }
                                    }
                                }
                            }

                            if (SubmissionResult == TSubmitChangesResult.scrOK)
                            {
                                TLogging.LogAtLevel(6,
                                    "TPartnerEditUIConnector.SubmitChanges: Before check for new Partner for Recent Partner handling...");

                                // Check if this is a new Partner
                                if ((InspectDS.Tables.Contains(PPartnerTable.GetTableName()))
                                    && ((InspectDS.PPartner.Rows.Count != 0) && ((!InspectDS.PPartner[0].HasVersion(DataRowVersion.Original)))))
                                {
                                    // Partner is new Partner > add to list of recent partners. (If the
                                    // Partner was not new then this was already done in LoadData.)
                                    TRecentPartnersHandling.AddRecentlyUsedPartner(FPartnerKey, FPartnerClass, true,
                                        TLastPartnerUse.lpuMailroomPartner);
                                    TLogging.LogAtLevel(6, "TPartnerEditUIConnector.SubmitChanges: Set Partner as Recent Partner.");
                                }

                                if (TLogging.DebugLevel >= 4)
                                {
                                    LogAfterSaving(InspectDS);
                                }

                                // Must call AcceptChanges so that DataSet.Merge on Client side works
                                // properly if Primary Keys have been changed!
                                InspectDS.AcceptChanges();

                                SubmissionResult = TSubmitChangesResult.scrOK;

                                /* $IFDEF DEBUGMODE if TLogging.DL >= 9 then Console.WriteLine('Location[0] LocationKey: ' + FSubmissionDS.PLocation[0].LocationKey.ToString + '; PartnerLocation[0] LocationKey: ' +
                                 *FSubmissionDS.PPartnerLocation[0].LocationKey.ToString);$ENDIF */
                                TLogging.LogAtLevel(8, "TPartnerEditUIConnector.SubmitChanges: Transaction will get committed!");
                            }
                            else
                            {
                                TLogging.LogAtLevel(8, "TPartnerEditUIConnector.SubmitChanges: Transaction will get ROLLED BACK!");
                            }
                        }
                        catch (Exception e)
                        {
                            TLogging.Log(e.Message);
                            TLogging.Log(e.StackTrace);

                            throw;
                        }
                    });
            }
            else
            {
                TLogging.LogAtLevel(8, "TPartnerEditUIConnector.SubmitChanges: AInspectDS = nil!");
                SubmissionResult = TSubmitChangesResult.scrNothingToBeSaved;
            }

            AInspectDS = FSubmissionDS;
            AResponseDS = ResponseDS;

            return SubmissionResult;
        }
        /// <summary>
        /// todoComment
        ///
        /// @comment Must only be called for Partners of Partner Class FAMILY - the
        /// function does no checks on that and will fail for other Partner Classes!
        /// </summary>
        /// <param name="APartnerLocationRow"></param>
        /// <param name="APartnerKey"></param>
        /// <param name="AResponseDS"></param>
        /// <param name="ASubmitChangesTransaction"></param>
        /// <param name="AAddressChangedPromotionDT"></param>
        /// <param name="AChangeLocationParametersDT"></param>
        /// <param name="APartnerLocationTable"></param>
        /// <param name="AVerificationResult"></param>
        /// <returns></returns>
        private static TSubmitChangesResult PerformPartnerLocationChangeChecks(PPartnerLocationRow APartnerLocationRow,
            Int64 APartnerKey,
            ref PartnerAddressAggregateTDS AResponseDS,
            TDBTransaction ASubmitChangesTransaction,
            ref PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable AAddressChangedPromotionDT,
            ref PartnerAddressAggregateTDSChangePromotionParametersTable AChangeLocationParametersDT,
            ref PPartnerLocationTable APartnerLocationTable,
            ref TVerificationResultCollection AVerificationResult)
        {
            TSubmitChangesResult ReturnValue;
            DataView PropagateLocationParametersDV;
            DataView PropagateLocationParametersProcessedDV;
            Boolean UpdatePartnerLocations;

            Int64[, ] UpdatePartnerLocationOtherPersons;
            OdbcParameter[] ParametersArray;
            DataSet PartnerLocationModifyDS;
            StringCollection ChangedFieldsColl;
            String[] ChangedFieldsArr;
            Int32 Counter;
            Int32 Counter2;
            Int32 Counter3;
            Int32 Counter4;
            PPartnerLocationTable PartnerLocationModificationDT;
//          TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: AAddressChangedPromotionDT.Rows.Count: " + AAddressChangedPromotionDT.Rows.Count.ToString());

            UpdatePartnerLocations = false;

            if (CheckPartnerLocationChange(APartnerLocationRow, APartnerKey, ref AAddressChangedPromotionDT, ASubmitChangesTransaction,
                    out UpdatePartnerLocations, out UpdatePartnerLocationOtherPersons, ref AChangeLocationParametersDT))
            {
                // Check if there is a Parameter Row for the LocationKey we are looking at
                PropagateLocationParametersDV = new DataView(AAddressChangedPromotionDT,
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " +
                    APartnerLocationRow[PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName(),
                                        DataRowVersion.Original].ToString() + " AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() +
                    " = " +
                    APartnerLocationRow[PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName(),
                                        DataRowVersion.Original].ToString() + " AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetPartnerLocationChangeDBName() + " = true AND " +
                    PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() + " = false",
                    "",
                    DataViewRowState.CurrentRows);

                // APartnerLocationRow.SiteKey.ToString
                // APartnerLocationRow.LocationKey.ToString
                if (PropagateLocationParametersDV.Count > 0)
                {
//                  TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: PartnerLocation " + APartnerLocationRow.LocationKey.ToString() +
//                          ": PartnerLocation has been changed, decision on propagation is needed.");

                    /*
                     * More information is needed (usually via user interaction)
                     * -> stop processing here and return parameters
                     * (usually used for UI interaction)
                     */
                    if (AResponseDS == null)
                    {
//                      TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Creating AResponseDS.");
                        AResponseDS = new PartnerAddressAggregateTDS(MPartnerConstants.PARTNERADDRESSAGGREGATERESPONSE_DATASET);
                    }

//                  TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: AAddressAddedPromotionDT.Rows.Count: " + AAddressChangedPromotionDT.Rows.Count.ToString());
                    AResponseDS.Merge(AAddressChangedPromotionDT);

//                  TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Merged AAddressAddedPromotionDT into AResponseDS.");
                    AResponseDS.Merge(AChangeLocationParametersDT);
//                  TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Merged ChangePromotionParametersDT into AResponseDS.");
//                  TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: AResponseDS.Tables[" + MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME +
//                        "].Rows.Count: " + AResponseDS.Tables[MPartnerConstants.ADDRESSADDEDORCHANGEDPROMOTION_TABLENAME].Rows.Count.ToString());
                    ReturnValue = TSubmitChangesResult.scrInfoNeeded;
                    return ReturnValue;
                }
                else
                {
                    /*
                     * NOTE: If there are no Family Members, CheckPartnerLocationChange will
                     * return true, but the PropagateLocationParametersDV.Count will be 0, so
                     * the processing will also go here and find UpdatePartnerLocations false
                     * (default assigned at beginning), so nothing will happen.
                     */
                    if (UpdatePartnerLocations)
                    {
//                      TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: User made his/her choice regarding PartnerLocation Change promotion; now processing...");

                        /*
                         * User made his/her choice regarding PartnerLocation Change promotion;
                         * now process it
                         */
//                      TLogging.LogAtLevel(9,  "PerformPartnerLocationChangeChecks: Updated FAMILY PartnerLocation " + APartnerLocationRow.LocationKey.ToString() +
//                            ": changes should be assigned to " + Convert.ToInt32(UpdatePartnerLocationOtherPersons.GetLength(0)).ToString() + " PartnerLocations of PERSONs...");

                        PartnerLocationModifyDS = null;

                        // Find associated Parameter Row
                        PropagateLocationParametersProcessedDV = new DataView(
                            AAddressChangedPromotionDT, PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName() + " = " +
                            APartnerLocationRow[PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetSiteKeyDBName(),
                                                DataRowVersion.Original].ToString() + " AND " +
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName() + " = " +
                            APartnerLocationRow[PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetLocationKeyDBName(),
                                                DataRowVersion.Original].ToString() + " AND " +
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetPartnerLocationChangeDBName() +
                            " = true AND " +
                            PartnerAddressAggregateTDSAddressAddedOrChangedPromotionTable.GetAnswerProcessedClientSideDBName() +
                            " = true", "",
                            DataViewRowState.CurrentRows);

                        // APartnerLocationRow.SiteKey.ToString
                        // APartnerLocationRow.LocationKey.ToString

                        /*
                         * Create a Collection by splitting String 'ChangedFields' from the
                         * Parameter Row.
                         * The String contains: DBName, Label, OriginalValue, CurrentValue for
                         * each changed DataColumn.
                         */
                        ChangedFieldsColl =
                            StringHelper.StrSplit(((PartnerAddressAggregateTDSAddressAddedOrChangedPromotionRow)
                                                   PropagateLocationParametersProcessedDV[0].
                                                   Row).ChangedFields, "|");
                        ChangedFieldsArr = new String[(Convert.ToInt16(ChangedFieldsColl.Count / 4.0))];
//                      TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Length(ChangedFieldsArr): " + Convert.ToInt16(ChangedFieldsArr.Length).ToString());

                        Counter = 0;
                        Counter2 = 0;

                        // Build array that contains just the DB names of the changed fields
                        while (Counter2 <= ChangedFieldsArr.Length - 1)
                        {
                            ChangedFieldsArr[Counter2] = ChangedFieldsColl[Counter];

                            // position Counter to next DB Field name
                            Counter = Counter + 4;
                            Counter2 = Counter2 + 1;
                        }

                        /*
                         * Load data for each Person's PartnerLocation to which the changes to
                         * the Family's PartnerLocation should be taken over and apply the change.
                         */
                        PartnerLocationModifyDS = new DataSet();
                        PartnerLocationModifyDS.Tables.Add(new PPartnerLocationTable(PPartnerLocationTable.GetTableName()));

                        for (Counter3 = 0; Counter3 <= UpdatePartnerLocationOtherPersons.GetLength(0) - 1; Counter3 += 1)
                        {
                            ParametersArray = new OdbcParameter[3];
                            ParametersArray[0] = new OdbcParameter("", OdbcType.Decimal, 10);
                            ParametersArray[0].Value = (System.Object)(UpdatePartnerLocationOtherPersons[Counter3, 0]);
                            ParametersArray[1] = new OdbcParameter("", OdbcType.Decimal, 10);
                            ParametersArray[1].Value = (System.Object)(UpdatePartnerLocationOtherPersons[Counter3, 1]);
                            ParametersArray[2] = new OdbcParameter("", OdbcType.Int);
                            ParametersArray[2].Value = (System.Object)(UpdatePartnerLocationOtherPersons[Counter3, 2]);
                            PartnerLocationModifyDS = DBAccess.GDBAccessObj.Select(PartnerLocationModifyDS,
                                "SELECT * " + "FROM PUB_" + PPartnerLocationTable.GetTableDBName() + ' ' + "WHERE " +
                                PPartnerLocationTable.GetPartnerKeyDBName() + " = ? " + "AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = ? " +
                                "AND " + PPartnerLocationTable.GetLocationKeyDBName() + " = ?",
                                PPartnerLocationTable.GetTableName(),
                                ASubmitChangesTransaction,
                                ParametersArray);
                            PartnerLocationModificationDT = ((PPartnerLocationTable)PartnerLocationModifyDS.Tables[0]);

                            // Take over defined Columns' contents (only those Columns containing
                            // changes) of the FAMILY's PartnerLocation to the loaded
                            // PartnerLocation
                            for (Counter4 = 0; Counter4 <= ChangedFieldsArr.Length - 1; Counter4 += 1)
                            {
                                PartnerLocationModificationDT[0][ChangedFieldsArr[Counter4]] = APartnerLocationRow[ChangedFieldsArr[Counter4]];
//                              TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Changes to Column " + ChangedFieldsArr[Counter4].ToString() +
//                                      " taken over for LocationKey " + PartnerLocationModificationDT[0][PPartnerLocationTable.GetLocationKeyDBName()].ToString());
                            }

                            // Submit the changes of the processed Person's PartnerLocation record to the DB
                            PPartnerLocationAccess.SubmitChanges(PartnerLocationModificationDT, ASubmitChangesTransaction);

                            // Don't keep the Person's PPartnerLocation in memory that we just processed!
                            PartnerLocationModifyDS.Tables[0].Rows.Clear();
                        }
                    }
                }

                ReturnValue = TSubmitChangesResult.scrOK;
            }
            else
            {
//              TLogging.LogAtLevel(9, "PerformPartnerLocationChangeChecks: Location " + APartnerLocationRow.LocationKey.ToString() + ": User cancelled the selection - stopping the whole saving process!");

                /*
                 * User cancelled the selection - stop the whole saving process!
                 */
                AVerificationResult.Add(new TVerificationResult("Partner-specific Address Data Change Promotion: Information",
                        "No changes were saved because the Partner-specific Address Data Promotion dialog was cancelled by the user.",
                        "Saving cancelled by user", "", TResultSeverity.Resv_Noncritical));
                ReturnValue = TSubmitChangesResult.scrError;
            }

            return ReturnValue;
        }