Only notify clients actually affected by a conflict
Bisher bekam jeder Arbeitsplatz, der den Konflikt-Kontakt im Adressbuch hat, den Hinweis - auch wenn er den Wert gar nicht selbst gepflegt hat. Jetzt zeigt ein Client eine fremde Konflikt-Notiz nur, wenn er den Kontakt hat UND sein eigener Feldwert vom uebernommenen (Gewinner-)Wert abweicht. Die Pruefung laeuft VOR dem Sync (gegen den eigenen Mapping-Snapshot), bevor der Sync den Stand auf den Gewinner-Wert angleicht. - FieldConflict/ConflictNotice: stabiler FieldKey zusaetzlich zum Anzeige-Label. - ContactMerger: GetValue/ValuesEqual per FieldKey (telefon-normalisiert). - ConflictNotifier.GetPending: Filter "eigener Wert != Gewinner-Wert", bekommt StarfaceId -> eigener Kontaktstand. - MainForm zeigt die Hinweise jetzt vor dem Sync und liefert den eigenen Stand aus den Mapping-Snapshots. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ namespace StarfaceOutlookSync.Services
|
||||
{
|
||||
private class FieldDef
|
||||
{
|
||||
public string Key;
|
||||
public string Label;
|
||||
public Func<UnifiedContact, string> Get;
|
||||
public Action<UnifiedContact, string> Set;
|
||||
@@ -23,28 +24,43 @@ namespace StarfaceOutlookSync.Services
|
||||
|
||||
private static readonly FieldDef[] Fields = new[]
|
||||
{
|
||||
new FieldDef { Label = "Vorname", Get = c => c.FirstName, Set = (c, v) => c.FirstName = v },
|
||||
new FieldDef { Label = "Nachname", Get = c => c.LastName, Set = (c, v) => c.LastName = v },
|
||||
new FieldDef { Label = "Firma", Get = c => c.Company, Set = (c, v) => c.Company = v },
|
||||
new FieldDef { Label = "Position", Get = c => c.JobTitle, Set = (c, v) => c.JobTitle = v },
|
||||
new FieldDef { Label = "E-Mail", Get = c => c.Email, Set = (c, v) => c.Email = v },
|
||||
new FieldDef { Label = "E-Mail 2", Get = c => c.EmailSecondary, Set = (c, v) => c.EmailSecondary = v },
|
||||
new FieldDef { Label = "Telefon", Get = c => c.PhoneWork, Set = (c, v) => c.PhoneWork = v, IsPhone = true },
|
||||
new FieldDef { Label = "Mobil", Get = c => c.PhoneMobile, Set = (c, v) => c.PhoneMobile = v, IsPhone = true },
|
||||
new FieldDef { Label = "Telefon privat", Get = c => c.PhoneHome, Set = (c, v) => c.PhoneHome = v, IsPhone = true },
|
||||
new FieldDef { Label = "Fax", Get = c => c.Fax, Set = (c, v) => c.Fax = v, IsPhone = true },
|
||||
new FieldDef { Label = "Strasse", Get = c => c.Street, Set = (c, v) => c.Street = v },
|
||||
new FieldDef { Label = "Ort", Get = c => c.City, Set = (c, v) => c.City = v },
|
||||
new FieldDef { Label = "PLZ", Get = c => c.PostalCode, Set = (c, v) => c.PostalCode = v },
|
||||
new FieldDef { Label = "Bundesland", Get = c => c.State, Set = (c, v) => c.State = v },
|
||||
new FieldDef { Label = "Land", Get = c => c.Country, Set = (c, v) => c.Country = v },
|
||||
new FieldDef { Label = "Webseite", Get = c => c.Website, Set = (c, v) => c.Website = v },
|
||||
new FieldDef { Label = "Notizen", Get = c => c.Notes, Set = (c, v) => c.Notes = v },
|
||||
new FieldDef { Label = "Anrede", Get = c => c.Salutation, Set = (c, v) => c.Salutation = v },
|
||||
new FieldDef { Label = "Titel", Get = c => c.Title, Set = (c, v) => c.Title = v },
|
||||
new FieldDef { Label = "Geburtstag", Get = c => c.Birthday, Set = (c, v) => c.Birthday = v },
|
||||
new FieldDef { Key = "FirstName", Label = "Vorname", Get = c => c.FirstName, Set = (c, v) => c.FirstName = v },
|
||||
new FieldDef { Key = "LastName", Label = "Nachname", Get = c => c.LastName, Set = (c, v) => c.LastName = v },
|
||||
new FieldDef { Key = "Company", Label = "Firma", Get = c => c.Company, Set = (c, v) => c.Company = v },
|
||||
new FieldDef { Key = "JobTitle", Label = "Position", Get = c => c.JobTitle, Set = (c, v) => c.JobTitle = v },
|
||||
new FieldDef { Key = "Email", Label = "E-Mail", Get = c => c.Email, Set = (c, v) => c.Email = v },
|
||||
new FieldDef { Key = "EmailSecondary", Label = "E-Mail 2", Get = c => c.EmailSecondary, Set = (c, v) => c.EmailSecondary = v },
|
||||
new FieldDef { Key = "PhoneWork", Label = "Telefon", Get = c => c.PhoneWork, Set = (c, v) => c.PhoneWork = v, IsPhone = true },
|
||||
new FieldDef { Key = "PhoneMobile", Label = "Mobil", Get = c => c.PhoneMobile, Set = (c, v) => c.PhoneMobile = v, IsPhone = true },
|
||||
new FieldDef { Key = "PhoneHome", Label = "Telefon privat", Get = c => c.PhoneHome, Set = (c, v) => c.PhoneHome = v, IsPhone = true },
|
||||
new FieldDef { Key = "Fax", Label = "Fax", Get = c => c.Fax, Set = (c, v) => c.Fax = v, IsPhone = true },
|
||||
new FieldDef { Key = "Street", Label = "Strasse", Get = c => c.Street, Set = (c, v) => c.Street = v },
|
||||
new FieldDef { Key = "City", Label = "Ort", Get = c => c.City, Set = (c, v) => c.City = v },
|
||||
new FieldDef { Key = "PostalCode", Label = "PLZ", Get = c => c.PostalCode, Set = (c, v) => c.PostalCode = v },
|
||||
new FieldDef { Key = "State", Label = "Bundesland", Get = c => c.State, Set = (c, v) => c.State = v },
|
||||
new FieldDef { Key = "Country", Label = "Land", Get = c => c.Country, Set = (c, v) => c.Country = v },
|
||||
new FieldDef { Key = "Website", Label = "Webseite", Get = c => c.Website, Set = (c, v) => c.Website = v },
|
||||
new FieldDef { Key = "Notes", Label = "Notizen", Get = c => c.Notes, Set = (c, v) => c.Notes = v },
|
||||
new FieldDef { Key = "Salutation", Label = "Anrede", Get = c => c.Salutation, Set = (c, v) => c.Salutation = v },
|
||||
new FieldDef { Key = "Title", Label = "Titel", Get = c => c.Title, Set = (c, v) => c.Title = v },
|
||||
new FieldDef { Key = "Birthday", Label = "Geburtstag", Get = c => c.Birthday, Set = (c, v) => c.Birthday = v },
|
||||
};
|
||||
|
||||
/// <summary>Liest den Wert eines Feldes per stabilem Schluessel.</summary>
|
||||
public static string GetValue(UnifiedContact c, string key)
|
||||
{
|
||||
if (c == null || string.IsNullOrEmpty(key)) return "";
|
||||
var f = Fields.FirstOrDefault(x => x.Key == key);
|
||||
return f == null ? "" : (f.Get(c) ?? "");
|
||||
}
|
||||
|
||||
/// <summary>Vergleicht zwei Feldwerte (telefon-normalisiert je nach Feld).</summary>
|
||||
public static bool ValuesEqual(string key, string a, string b)
|
||||
{
|
||||
var f = Fields.FirstOrDefault(x => x.Key == key);
|
||||
return Equal(a ?? "", b ?? "", f?.IsPhone ?? false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fuehrt den Outlook- und Starface-Stand gegen ihre jeweilige Baseline
|
||||
/// zusammen. outlookWins entscheidet bei echten Feld-Konflikten.
|
||||
@@ -95,6 +111,7 @@ namespace StarfaceOutlookSync.Services
|
||||
StarfaceId = starface.StarfaceId,
|
||||
ContactName = outlook.DisplayName,
|
||||
Field = f.Label,
|
||||
FieldKey = f.Key,
|
||||
OutlookValue = olv,
|
||||
StarfaceValue = sfv,
|
||||
Winner = outlookWins ? "Outlook" : "Starface"
|
||||
|
||||
Reference in New Issue
Block a user