fix(crm): store contact addresses via ContactInfo Address type (#288)
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 4s
Tests / Test (Go stable) (pull_request) Successful in 1m1s
Tests / Test (Go 1.25) (pull_request) Successful in 1m1s
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 4s
Tests / Test (Go stable) (pull_request) Successful in 1m1s
Tests / Test (Go 1.25) (pull_request) Successful in 1m1s
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package catalog
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestMergeAddressesDedup(t *testing.T) {
|
||||
dst := []Address{{Street: "Weg 1", City: "Stadt", Zip: "1"}}
|
||||
got := mergeAddresses(dst, []Address{
|
||||
{Street: "weg 1", City: "stadt", Zip: "1"}, // duplicate (case-insensitive)
|
||||
{Street: "Weg 2", City: "Stadt", Zip: "2"}, // new
|
||||
})
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("got %d addresses, want 2: %+v", len(got), got)
|
||||
}
|
||||
if got[1].Street != "Weg 2" {
|
||||
t.Errorf("second = %+v", got[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEntryAddressesYAML(t *testing.T) {
|
||||
doc := &Document{Entries: []Entry{{
|
||||
ID: "person:max maier", Kind: "person", Name: "Max Maier",
|
||||
Addresses: []Address{{Street: "Weg 1", City: "Stadt", Zip: "12345", Category: "Billing", Primary: true}},
|
||||
}}}
|
||||
merged := MergeDocs(doc)
|
||||
if len(merged.Entries) != 1 || len(merged.Entries[0].Addresses) != 1 {
|
||||
t.Fatalf("merged = %+v", merged.Entries)
|
||||
}
|
||||
}
|
||||
@@ -195,5 +195,16 @@ func ensureContactInfos(ctx context.Context, client *onlyoffice.Client, contactI
|
||||
return fmt.Errorf("add phone %s: %w", ph, err)
|
||||
}
|
||||
}
|
||||
for _, a := range e.Addresses {
|
||||
if strings.TrimSpace(a.Street) == "" && strings.TrimSpace(a.City) == "" && strings.TrimSpace(a.Zip) == "" {
|
||||
continue
|
||||
}
|
||||
if onlyoffice.HasContactAddress(existing, a.Street, a.City, a.Zip, a.Category) {
|
||||
continue
|
||||
}
|
||||
if _, err := client.AddContactAddress(ctx, contactID, a.Street, a.City, a.State, a.Zip, a.Country, a.Category, a.Primary); err != nil {
|
||||
return fmt.Errorf("add address %s: %w", strings.TrimSpace(a.Street), err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+50
-17
@@ -12,25 +12,38 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Address is one postal address of a catalog row. Category is the OO
|
||||
// AddressCategory label (Home|Postal|Office|Billing|Other|Work).
|
||||
type Address struct {
|
||||
Street string `yaml:"street,omitempty"`
|
||||
City string `yaml:"city,omitempty"`
|
||||
State string `yaml:"state,omitempty"`
|
||||
Zip string `yaml:"zip,omitempty"`
|
||||
Country string `yaml:"country,omitempty"`
|
||||
Category string `yaml:"category,omitempty"`
|
||||
Primary bool `yaml:"primary,omitempty"`
|
||||
}
|
||||
|
||||
// Entry is one catalog row (person or company).
|
||||
type Entry struct {
|
||||
ID string `yaml:"id"`
|
||||
Kind string `yaml:"kind"` // person | company
|
||||
Name string `yaml:"name,omitempty"`
|
||||
First string `yaml:"first,omitempty"`
|
||||
Last string `yaml:"last,omitempty"`
|
||||
Emails []string `yaml:"emails,omitempty"`
|
||||
Phones []string `yaml:"phones,omitempty"`
|
||||
Org string `yaml:"org,omitempty"`
|
||||
Sources []string `yaml:"sources,omitempty"`
|
||||
Zone string `yaml:"zone"`
|
||||
Role string `yaml:"role"`
|
||||
OOID string `yaml:"oo_id,omitempty"`
|
||||
Approve bool `yaml:"approve"`
|
||||
Status string `yaml:"status,omitempty"` // new | exists | conflict | applied | skipped
|
||||
Notes string `yaml:"notes,omitempty"`
|
||||
Remote string `yaml:"remote,omitempty"`
|
||||
GitRoot string `yaml:"git_root,omitempty"`
|
||||
ID string `yaml:"id"`
|
||||
Kind string `yaml:"kind"` // person | company
|
||||
Name string `yaml:"name,omitempty"`
|
||||
First string `yaml:"first,omitempty"`
|
||||
Last string `yaml:"last,omitempty"`
|
||||
Emails []string `yaml:"emails,omitempty"`
|
||||
Phones []string `yaml:"phones,omitempty"`
|
||||
Addresses []Address `yaml:"addresses,omitempty"`
|
||||
Org string `yaml:"org,omitempty"`
|
||||
Sources []string `yaml:"sources,omitempty"`
|
||||
Zone string `yaml:"zone"`
|
||||
Role string `yaml:"role"`
|
||||
OOID string `yaml:"oo_id,omitempty"`
|
||||
Approve bool `yaml:"approve"`
|
||||
Status string `yaml:"status,omitempty"` // new | exists | conflict | applied | skipped
|
||||
Notes string `yaml:"notes,omitempty"`
|
||||
Remote string `yaml:"remote,omitempty"`
|
||||
GitRoot string `yaml:"git_root,omitempty"`
|
||||
}
|
||||
|
||||
// Document is the on-disk catalog file.
|
||||
@@ -136,6 +149,7 @@ func mergeEntry(dst, src *Entry) {
|
||||
dst.Sources = uniqueStrings(append(dst.Sources, src.Sources...))
|
||||
dst.Emails = uniqueEmails(append(dst.Emails, src.Emails...))
|
||||
dst.Phones = uniqueStrings(append(dst.Phones, src.Phones...))
|
||||
dst.Addresses = mergeAddresses(dst.Addresses, src.Addresses)
|
||||
if dst.First == "" {
|
||||
dst.First = src.First
|
||||
}
|
||||
@@ -176,6 +190,25 @@ func mergeEntry(dst, src *Entry) {
|
||||
}
|
||||
}
|
||||
|
||||
// mergeAddresses appends src addresses not already present (by street/city/zip).
|
||||
func mergeAddresses(dst, src []Address) []Address {
|
||||
for _, a := range src {
|
||||
exists := false
|
||||
for _, b := range dst {
|
||||
if strings.EqualFold(strings.TrimSpace(a.Street), strings.TrimSpace(b.Street)) &&
|
||||
strings.EqualFold(strings.TrimSpace(a.City), strings.TrimSpace(b.City)) &&
|
||||
strings.EqualFold(strings.TrimSpace(a.Zip), strings.TrimSpace(b.Zip)) {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
dst = append(dst, a)
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func uniqueEmails(in []string) []string {
|
||||
seen := map[string]struct{}{}
|
||||
var out []string
|
||||
|
||||
Reference in New Issue
Block a user