Skip to content

Commit ad5ef8c

Browse files
kitallisclaude
andcommitted
Deduplicate entries and add invoice links
- Skip pending entries if there's a completed one for the same date - Add clickable invoice URL for each payment entry Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9ef4562 commit ad5ef8c

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

main.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,56 @@ func getEntryAccountID(e SubscriptionEntry) string {
833833
return ""
834834
}
835835

836+
func getEntryInvoiceUrl(e SubscriptionEntry) string {
837+
if order, ok := e.Order.(map[string]any); ok {
838+
if url, ok := order["invoiceUrl"].(string); ok {
839+
return url
840+
}
841+
}
842+
return ""
843+
}
844+
845+
func getEntryDate(e SubscriptionEntry) string {
846+
if order, ok := e.Order.(map[string]any); ok {
847+
// Prefer the ISO date for consistent comparison
848+
if date, ok := order["changedDisplayISO8601"].(string); ok && date != "" {
849+
return date
850+
}
851+
if date, ok := order["changedDisplay"].(string); ok && date != "" {
852+
return date
853+
}
854+
}
855+
if e.ChangedDisplay != "" {
856+
return e.ChangedDisplay
857+
}
858+
return e.BeginPeriodDate
859+
}
860+
861+
// deduplicateEntries removes pending entries if there's a completed entry for the same date
862+
func deduplicateEntries(entries []SubscriptionEntry) []SubscriptionEntry {
863+
// First pass: collect dates that have completed entries
864+
completedDates := make(map[string]bool)
865+
for _, e := range entries {
866+
if getEntryCompleted(e) {
867+
date := getEntryDate(e)
868+
completedDates[date] = true
869+
}
870+
}
871+
872+
// Second pass: filter out pending entries for dates that have completed ones
873+
var result []SubscriptionEntry
874+
for _, e := range entries {
875+
date := getEntryDate(e)
876+
if !getEntryCompleted(e) && completedDates[date] {
877+
// Skip this pending entry - there's a completed one for the same date
878+
continue
879+
}
880+
result = append(result, e)
881+
}
882+
883+
return result
884+
}
885+
836886
func digestHandler(w http.ResponseWriter, r *http.Request) {
837887
if r.Method != http.MethodGet && r.Method != http.MethodPost {
838888
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
@@ -1026,20 +1076,24 @@ func formatCustomerSection(cd *CustomerDigest) string {
10261076
continue
10271077
}
10281078

1029-
for _, e := range sub.Entries {
1079+
// Deduplicate: remove pending entries if completed exists for same date
1080+
entries := deduplicateEntries(sub.Entries)
1081+
1082+
for _, e := range entries {
10301083
status := ":white_check_mark:"
10311084
if !getEntryCompleted(e) {
10321085
status = ":hourglass_flowing_sand:"
10331086
}
10341087

10351088
amount := getEntryTotal(e)
1089+
date := getEntryDate(e)
1090+
invoiceUrl := getEntryInvoiceUrl(e)
10361091

1037-
date := e.ChangedDisplay
1038-
if date == "" {
1039-
date = e.BeginPeriodDate
1092+
if invoiceUrl != "" {
1093+
section += fmt.Sprintf("\n %s <%s|%s> • %s", status, invoiceUrl, date, amount)
1094+
} else {
1095+
section += fmt.Sprintf("\n %s %s • %s", status, date, amount)
10401096
}
1041-
1042-
section += fmt.Sprintf("\n %s %s • %s", status, date, amount)
10431097
}
10441098
}
10451099

0 commit comments

Comments
 (0)