Files
go-onlyoffice/crm_normalize.go
T
eSlider e07cf743f9 feat(catalog): mbox header scan, company legal-suffix match, apply order
Add --mbox-headers for Thunderbird folder files; strip GmbH/& Co. KG in
CompanyGroupingKey; FindCompany falls back to full scan; apply companies
before persons. Tightens role-mailbox noise filters.
2026-07-26 11:34:42 +01:00

126 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package onlyoffice
import (
"regexp"
"strings"
)
var multiSpace = regexp.MustCompile(`\s+`)
// sloganSeparators split a company name from a trailing tagline/slogan.
var sloganSeparators = []string{" — ", " – ", " - ", "—", "–"}
// companyLegalSuffix matches trailing legal-form tokens (GmbH, & Co. KG, …).
var companyLegalSuffix = regexp.MustCompile(`(?i)[\s,]*(&\s*co\.?\s*kg\.?|co\.?\s*kg\.?|gmbh|ag|ltd\.?|llc\.?|inc\.?|plc\.?|s\.?l\.?|sarl|b\.?v\.?)\s*$`)
// StripSloganSuffix returns the part before an em/en dash tagline, e.g.
// "Affirm — Fraud Engineering" → "Affirm".
func StripSloganSuffix(s string) string {
s = strings.TrimSpace(s)
for _, sep := range sloganSeparators {
if i := strings.Index(s, sep); i > 0 {
return strings.TrimSpace(s[:i])
}
}
return s
}
// StripCompanyLegalSuffix removes trailing GmbH / & Co. KG / Ltd / … tokens.
func StripCompanyLegalSuffix(s string) string {
s = strings.TrimSpace(s)
s = strings.TrimRight(s, ",; ")
for {
next := companyLegalSuffix.ReplaceAllString(s, "")
next = strings.TrimRight(strings.TrimSpace(next), ",; ")
if next == s || next == "" {
return s
}
s = next
}
}
// CompanyGroupingKey normalizes a company name for dedupe (ignores slogans and legal suffixes).
func CompanyGroupingKey(s string) string {
return NormalizeCompanyName(StripCompanyLegalSuffix(StripSloganSuffix(s)))
}
// NormalizeCompanyName lowercases and collapses whitespace for grouping.
func NormalizeCompanyName(s string) string {
return collapseKey(s)
}
// NormalizePersonKey builds a grouping key from first and last name.
func NormalizePersonKey(first, last string) string {
return collapseKey(strings.TrimSpace(first) + " " + strings.TrimSpace(last))
}
// NormalizeOpportunityTitle lowercases and trims a deal title for exact dedupe.
func NormalizeOpportunityTitle(s string) string {
return collapseKey(s)
}
// StripCompanySuffix removes a trailing " @ Company" segment when present.
func StripCompanySuffix(title string) string {
title = strings.TrimSpace(title)
if i := strings.LastIndex(title, " @ "); i >= 0 {
return strings.TrimSpace(title[:i])
}
return title
}
// FixDealTitle strips a leading @, normalizes separator spacing, and collapses
// empty-position titles like " @ contoso" to "contoso".
func FixDealTitle(s string) string {
s = strings.TrimSpace(s)
for strings.HasPrefix(s, "@") {
s = strings.TrimSpace(strings.TrimPrefix(s, "@"))
}
if s == "" {
return ""
}
if i := strings.Index(s, "@"); i >= 0 {
left := strings.TrimSpace(s[:i])
right := strings.TrimSpace(s[i+1:])
if left == "" && right != "" {
return right
}
if left != "" && right != "" {
return left + " @ " + right
}
}
return s
}
// ContactInfoKey groups contact info rows by type and normalized value.
func ContactInfoKey(infoType, value string) string {
return strings.ToLower(strings.TrimSpace(infoType)) + "|" + strings.ToLower(strings.TrimSpace(value))
}
// MemberDisplayKey normalizes a member displayName for duplicate detection.
func MemberDisplayKey(displayName string) string {
return CompanyGroupingKey(displayName)
}
func collapseKey(s string) string {
s = strings.TrimSpace(s)
s = multiSpace.ReplaceAllString(s, " ")
return strings.ToLower(s)
}
// OpportunityTitlesMatch reports whether two deal titles refer to the same role+company.
func OpportunityTitlesMatch(a, b string) bool {
return DealTitleKey(a, false) == DealTitleKey(b, false)
}
func DealTitleForApplication(position, company string) string {
position = strings.TrimSpace(position)
company = strings.TrimSpace(company)
if company == "" {
return position
}
if position == "" {
return company
}
return position + " @ " + company
}