44 lines
1.3 KiB
Go
44 lines
1.3 KiB
Go
package growth
|
|
|
|
import (
|
|
"slices"
|
|
"time"
|
|
)
|
|
|
|
type Session struct {
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
Status string `json:"status"`
|
|
AmountRial int64 `json:"amountRial"`
|
|
}
|
|
|
|
// AggregateDaily groups already-authorized, scope-filtered sessions by Tehran
|
|
// local day. Paid and Verified are the only successful bank-payment statuses.
|
|
func AggregateDaily(sessions []Session, catalog []Event) []DailyPoint {
|
|
byDate := make(map[string]DailyPoint)
|
|
for _, session := range sessions {
|
|
local := session.CreatedAt.In(tehranLocation())
|
|
date := time.Date(local.Year(), local.Month(), local.Day(), 0, 0, 0, 0, tehranLocation())
|
|
key := dayKey(date)
|
|
point := byDate[key]
|
|
point.Date = date
|
|
point.SessionCount++
|
|
if session.Status == "Paid" || session.Status == "Verified" {
|
|
point.PaidSessionCount++
|
|
point.PaidAmountRial += session.AmountRial
|
|
}
|
|
byDate[key] = point
|
|
}
|
|
points := make([]DailyPoint, 0, len(byDate))
|
|
for _, point := range byDate {
|
|
for _, event := range catalog {
|
|
if !dateBefore(point.Date, event.StartDate) && !dateAfter(point.Date, event.EndDate) {
|
|
point.EventIDs = append(point.EventIDs, event.ID)
|
|
}
|
|
}
|
|
slices.Sort(point.EventIDs)
|
|
points = append(points, point)
|
|
}
|
|
slices.SortFunc(points, func(a, b DailyPoint) int { return a.Date.Compare(b.Date) })
|
|
return points
|
|
}
|