feat: aggregate daily payment history by hour
This commit is contained in:
@@ -43,6 +43,7 @@ type RunScope struct {
|
||||
|
||||
type PaymentHistoryPoint struct {
|
||||
LocalDate string `json:"localDate"`
|
||||
LocalHour *int `json:"localHour,omitempty"`
|
||||
TotalSessions int64 `json:"totalSessions"`
|
||||
BankPaidSessions int64 `json:"bankPaidSessions"`
|
||||
BankPaidAmountRial int64 `json:"bankPaidAmountRial"`
|
||||
@@ -209,24 +210,25 @@ func (m metricValues) overview(period Period, history []PaymentHistoryPoint) map
|
||||
}
|
||||
|
||||
func (s *Service) paymentHistory(ctx context.Context, merchantID int64, period Period, terminalID string) ([]PaymentHistoryPoint, error) {
|
||||
rows, err := s.pool.Query(ctx, `SELECT (ps.created_at AT TIME ZONE 'Asia/Tehran')::date local_date,
|
||||
count(*),count(*) FILTER (WHERE ps.status IN ('Paid','Verified')),
|
||||
coalesce(sum(ps.amount_rial) FILTER (WHERE ps.status IN ('Paid','Verified')),0)
|
||||
FROM payment_sessions ps WHERE ps.merchant_id=$1 AND ps.created_at >= $2 AND ps.created_at < $3
|
||||
AND ($4='' OR ps.terminal_id=(SELECT id FROM terminals WHERE merchant_id=$1 AND source_key=$4))
|
||||
GROUP BY local_date ORDER BY local_date`, merchantID, period.StartAt, period.EndAt, terminalID)
|
||||
query, capacity := paymentHistoryQuery(period.PeriodType)
|
||||
rows, err := s.pool.Query(ctx, query, merchantID, period.StartAt, period.EndAt, terminalID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("querying payment history: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
points := make([]PaymentHistoryPoint, 0, 93)
|
||||
points := make([]PaymentHistoryPoint, 0, capacity)
|
||||
for rows.Next() {
|
||||
var date time.Time
|
||||
var localHour *int16
|
||||
var point PaymentHistoryPoint
|
||||
if err := rows.Scan(&date, &point.TotalSessions, &point.BankPaidSessions, &point.BankPaidAmountRial); err != nil {
|
||||
if err := rows.Scan(&date, &localHour, &point.TotalSessions, &point.BankPaidSessions, &point.BankPaidAmountRial); err != nil {
|
||||
return nil, fmt.Errorf("scanning payment history: %w", err)
|
||||
}
|
||||
point.LocalDate = date.Format(time.DateOnly)
|
||||
if localHour != nil {
|
||||
hour := int(*localHour)
|
||||
point.LocalHour = &hour
|
||||
}
|
||||
points = append(points, point)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
@@ -234,6 +236,25 @@ func (s *Service) paymentHistory(ctx context.Context, merchantID int64, period P
|
||||
}
|
||||
return points, nil
|
||||
}
|
||||
|
||||
func paymentHistoryQuery(periodType string) (string, int) {
|
||||
if periodType == "DAY" {
|
||||
return `SELECT (ps.created_at AT TIME ZONE 'Asia/Tehran')::date local_date,
|
||||
EXTRACT(HOUR FROM ps.created_at AT TIME ZONE 'Asia/Tehran')::smallint local_hour,
|
||||
count(*),count(*) FILTER (WHERE ps.status IN ('Paid','Verified')),
|
||||
coalesce(sum(ps.amount_rial) FILTER (WHERE ps.status IN ('Paid','Verified')),0)
|
||||
FROM payment_sessions ps WHERE ps.merchant_id=$1 AND ps.created_at >= $2 AND ps.created_at < $3
|
||||
AND ($4='' OR ps.terminal_id=(SELECT id FROM terminals WHERE merchant_id=$1 AND source_key=$4))
|
||||
GROUP BY local_date, local_hour ORDER BY local_date, local_hour`, 24
|
||||
}
|
||||
return `SELECT (ps.created_at AT TIME ZONE 'Asia/Tehran')::date local_date,
|
||||
NULL::smallint local_hour,
|
||||
count(*),count(*) FILTER (WHERE ps.status IN ('Paid','Verified')),
|
||||
coalesce(sum(ps.amount_rial) FILTER (WHERE ps.status IN ('Paid','Verified')),0)
|
||||
FROM payment_sessions ps WHERE ps.merchant_id=$1 AND ps.created_at >= $2 AND ps.created_at < $3
|
||||
AND ($4='' OR ps.terminal_id=(SELECT id FROM terminals WHERE merchant_id=$1 AND source_key=$4))
|
||||
GROUP BY local_date ORDER BY local_date`, 93
|
||||
}
|
||||
func timing(id string, p50, p95 *float64, samples, eligible int64) map[string]any {
|
||||
var a, b any
|
||||
if p50 != nil {
|
||||
|
||||
Reference in New Issue
Block a user