/// <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> /// todoComment /// </summary> /// <param name="APartnerKey"></param> /// <param name="ASiteKey"></param> /// <param name="APartnerLocationTable"></param> /// <param name="ATransaction"></param> private static void MakeSureLocation0IsNotPresent(Int64 APartnerKey, Int64 ASiteKey, PPartnerLocationTable APartnerLocationTable, TDBTransaction ATransaction) { PPartnerLocationTable TemplateDT; PPartnerLocationRow TemplateRow; if (APartnerLocationTable.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + APartnerKey.ToString() + " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = " + ASiteKey.ToString() + " AND " + PPartnerLocationTable.GetSiteKeyDBName() + " = 0", "", DataViewRowState.Deleted).Length == 0) { TemplateDT = new PPartnerLocationTable(); TemplateRow = TemplateDT.NewRowTyped(false); TemplateRow.PartnerKey = APartnerKey; TemplateRow.SiteKey = ASiteKey; TemplateRow.LocationKey = 0; /* * Currently we need to do a count before issuing the delete command. * If we don't do this, the DataStore raises a System.Data.Odbc.OdbcException * if such a row doesn't exist. The DataStore should really be fixed, then * counting before execution should not be necessary, which would be faster. */ if (Convert.ToInt32(PPartnerLocationAccess.CountUsingTemplate(TemplateRow, null, ATransaction)) > 0) { PPartnerLocationAccess.DeleteUsingTemplate(TemplateRow, null, ATransaction); // TLogging.LogAtLevel(9, "MakeSureLocation0IsNotPresent: Deleted PPartnerLoction that referenced Location 0."); } } else { // TLogging.LogAtLevel(9, "MakeSureLocation0IsNotPresent: Submitted DataSet contains a Deleted PPartnerLoction Location 0; will get deleted later."); } }
/// <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; }
/// Upgrade to version 2015-01 public static bool UpgradeDatabase201412_201501() { // There are no new tables and fields TDBTransaction SubmitChangesTransaction = null; TSubmitChangesResult SubmissionResult = TSubmitChangesResult.scrError; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { PPartnerAttributeTable partnerattributes = new PPartnerAttributeTable(); PPartnerLocationTable partnerlocations = PPartnerLocationAccess.LoadAll(SubmitChangesTransaction); // this update only works for very simple databases, only one partner location record per partner... if (partnerlocations.Count > 1000) { throw new Exception("the upgrade has not been optimized for huge databases"); } List <Int64> PartnerKeys = new List <Int64>(); foreach (PPartnerLocationRow partnerlocation in partnerlocations.Rows) { if (!PartnerKeys.Contains(partnerlocation.PartnerKey)) { PartnerKeys.Add(partnerlocation.PartnerKey); } else { TLogging.Log("several locations for partner " + partnerlocation.PartnerKey.ToString()); } } // Number for the p_sequence_i Column. Gets increased with every p_partner_attribute record that gets produced! int SequenceNumber = 0; foreach (Int64 partnerkey in PartnerKeys) { // Get that Partner's p_partner_location records from PPartnerLocationRecords DataRow[] CurrentRows = partnerlocations.Select(PPartnerLocationTable.GetPartnerKeyDBName() + " = " + partnerkey.ToString()); if (CurrentRows.Length == 0) { continue; } DataTable PPartnersLocationsDT = GetNewPPartnerLocationTableInstance(); foreach (DataRow r in CurrentRows) { PPartnersLocationsDT.Rows.Add(r.ItemArray); } TLocationPK bestAddress = Calculations.DetermineBestAddress(PPartnersLocationsDT); int IndexPhone = 0; int IndexEmail = 0; int IndexFax = 0; int IndexUrl = 0; int IndexMobile = 0; List <string> AvoidDuplicates = new List <string>(); string AttributeConcatenated; foreach (PPartnerLocationRow partnerlocation in PPartnersLocationsDT.Rows) { bool primaryAddress = (bestAddress.LocationKey == partnerlocation.LocationKey && bestAddress.SiteKey == partnerlocation.SiteKey); bool currentAddress = (((int)partnerlocation[PARTNERLOCATION_ICON_COLUMN]) == 1); bool businessAddress = (partnerlocation.LocationType == "BUSINESS" || partnerlocation.LocationType == "FIELD"); // TODO: avoid duplicate entries with the same type if (!partnerlocation.IsEmailAddressNull()) { PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.EmailAddress; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_EMAIL; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexEmail++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetEmailAddressNull(); } if (!partnerlocation.IsTelephoneNumberNull()) { if (!partnerlocation.IsExtensionNull()) { partnerlocation.TelephoneNumber += "-" + partnerlocation.Extension; } PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.TelephoneNumber; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_PHONE; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexPhone++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetTelephoneNumberNull(); } if (!partnerlocation.IsFaxNumberNull()) { if (!partnerlocation.IsFaxExtensionNull()) { partnerlocation.FaxNumber += "-" + partnerlocation.FaxExtension; } PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.FaxNumber; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_FAX; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexFax++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetFaxNumberNull(); } if (!partnerlocation.IsAlternateTelephoneNull()) { PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.AlternateTelephone; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_PHONE; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexPhone++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetAlternateTelephoneNull(); } if (!partnerlocation.IsMobileNumberNull()) { PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.MobileNumber; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_MOBILE_PHONE; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexMobile++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetMobileNumberNull(); } if (!partnerlocation.IsUrlNull()) { PPartnerAttributeRow partnerattribute = partnerattributes.NewRowTyped(); partnerattribute.Sequence = SequenceNumber++; partnerattribute.PartnerKey = partnerlocation.PartnerKey; partnerattribute.Value = partnerlocation.Url; partnerattribute.AttributeType = MPartnerConstants.ATTR_TYPE_WEBSITE; partnerattribute.Current = currentAddress; partnerattribute.Primary = primaryAddress; partnerattribute.Index = IndexUrl++; partnerattribute.Specialised = businessAddress; partnerattribute.NoLongerCurrentFrom = partnerlocation.DateGoodUntil; AttributeConcatenated = ConcatPartnerAttributes(partnerattribute); if (!AvoidDuplicates.Contains(AttributeConcatenated)) { partnerattributes.Rows.Add(partnerattribute); AvoidDuplicates.Add(AttributeConcatenated); } else { TLogging.Log("dropping duplicate " + AttributeConcatenated); } partnerlocation.SetUrlNull(); } } } PPartnerLocationAccess.SubmitChanges(partnerlocations, SubmitChangesTransaction); PPartnerAttributeAccess.SubmitChanges(partnerattributes, SubmitChangesTransaction); SubmissionResult = TSubmitChangesResult.scrOK; }); return(true); }