update dashboard
This commit is contained in:
parent
f391b6d853
commit
0c3e1db502
@ -504,6 +504,79 @@ func (r *AnalyticsRepository) GetMonthlyTrend(ctx context.Context, months int) (
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *AnalyticsRepository) GetMonthlyTrendByUserID(ctx context.Context, userID *uuid.UUID, months int) ([]map[string]interface{}, error) {
|
||||||
|
db := DBFromContext(ctx, r.db)
|
||||||
|
var results []map[string]interface{}
|
||||||
|
|
||||||
|
// Direct query (since we need to filter by user)
|
||||||
|
fallbackQuery := `
|
||||||
|
WITH monthly_data AS (
|
||||||
|
SELECT
|
||||||
|
TO_CHAR(date_trunc('month', li.created_at), 'Month') as month,
|
||||||
|
EXTRACT(YEAR FROM li.created_at) as year,
|
||||||
|
EXTRACT(MONTH FROM li.created_at) as month_num,
|
||||||
|
COUNT(DISTINCT li.id) as incoming_count,
|
||||||
|
0 as outgoing_count
|
||||||
|
FROM letters_incoming li
|
||||||
|
INNER JOIN letter_incoming_recipients lir ON lir.letter_id = li.id
|
||||||
|
WHERE li.deleted_at IS NULL
|
||||||
|
AND lir.recipient_user_id = ?
|
||||||
|
AND li.created_at >= NOW() - INTERVAL '%d months'
|
||||||
|
GROUP BY date_trunc('month', li.created_at), EXTRACT(YEAR FROM li.created_at), EXTRACT(MONTH FROM li.created_at)
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TO_CHAR(date_trunc('month', lo.created_at), 'Month') as month,
|
||||||
|
EXTRACT(YEAR FROM lo.created_at) as year,
|
||||||
|
EXTRACT(MONTH FROM lo.created_at) as month_num,
|
||||||
|
0 as incoming_count,
|
||||||
|
COUNT(DISTINCT lo.id) as outgoing_count
|
||||||
|
FROM letters_outgoing lo
|
||||||
|
INNER JOIN letter_outgoing_recipients lor ON lor.letter_id = lo.id
|
||||||
|
WHERE lo.deleted_at IS NULL
|
||||||
|
AND lor.user_id = ?
|
||||||
|
AND lo.created_at >= NOW() - INTERVAL '%d months'
|
||||||
|
GROUP BY date_trunc('month', lo.created_at), EXTRACT(YEAR FROM lo.created_at), EXTRACT(MONTH FROM lo.created_at)
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
month,
|
||||||
|
year,
|
||||||
|
SUM(incoming_count) as incoming_count,
|
||||||
|
SUM(outgoing_count) as outgoing_count,
|
||||||
|
SUM(incoming_count + outgoing_count) as total_count,
|
||||||
|
LAG(SUM(incoming_count + outgoing_count)) OVER (ORDER BY year, month_num) as prev_total
|
||||||
|
FROM monthly_data
|
||||||
|
GROUP BY month, year, month_num
|
||||||
|
ORDER BY year DESC, month_num DESC
|
||||||
|
LIMIT %d
|
||||||
|
`
|
||||||
|
|
||||||
|
fallbackQuery = fmt.Sprintf(fallbackQuery, months, months, months)
|
||||||
|
|
||||||
|
if err := db.Raw(fallbackQuery, userID, userID).Scan(&results).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate growth rate
|
||||||
|
for i := range results {
|
||||||
|
if results[i]["prev_total"] != nil {
|
||||||
|
prevVal, ok := results[i]["prev_total"].(float64)
|
||||||
|
if ok && prevVal > 0 {
|
||||||
|
current := getFloat64FromInterface(results[i]["total_count"])
|
||||||
|
results[i]["growth_rate"] = ((current - prevVal) / prevVal) * 100
|
||||||
|
} else {
|
||||||
|
results[i]["growth_rate"] = float64(0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
results[i]["growth_rate"] = float64(0)
|
||||||
|
}
|
||||||
|
delete(results[i], "prev_total")
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to safely convert interface{} to float64
|
// Helper function to safely convert interface{} to float64
|
||||||
func getFloat64FromInterface(v interface{}) float64 {
|
func getFloat64FromInterface(v interface{}) float64 {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
@ -727,17 +800,17 @@ func (r *AnalyticsRepository) GetDailyActivityByUserID(ctx context.Context, user
|
|||||||
SELECT
|
SELECT
|
||||||
DATE(created_at) as date,
|
DATE(created_at) as date,
|
||||||
TO_CHAR(created_at, 'Day') as day_of_week,
|
TO_CHAR(created_at, 'Day') as day_of_week,
|
||||||
COUNT(CASE WHEN type = 'incoming' THEN 1 END) as incoming_count,
|
COUNT(DISTINCT CASE WHEN type = 'incoming' THEN letter_id END) as incoming_count,
|
||||||
COUNT(CASE WHEN type = 'outgoing' THEN 1 END) as outgoing_count,
|
COUNT(DISTINCT CASE WHEN type = 'outgoing' THEN letter_id END) as outgoing_count,
|
||||||
0 as approved_count,
|
0 as approved_count,
|
||||||
0 as rejected_count
|
0 as rejected_count
|
||||||
FROM (
|
FROM (
|
||||||
SELECT li.created_at, 'incoming' as type
|
SELECT li.id as letter_id, li.created_at, 'incoming' as type
|
||||||
FROM letters_incoming li
|
FROM letters_incoming li
|
||||||
INNER JOIN letter_incoming_recipients lir ON lir.letter_id = li.id
|
INNER JOIN letter_incoming_recipients lir ON lir.letter_id = li.id
|
||||||
WHERE li.deleted_at IS NULL AND lir.recipient_user_id = ?
|
WHERE li.deleted_at IS NULL AND lir.recipient_user_id = ?
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT lo.created_at, 'outgoing' as type
|
SELECT lo.id as letter_id, lo.created_at, 'outgoing' as type
|
||||||
FROM letters_outgoing lo
|
FROM letters_outgoing lo
|
||||||
INNER JOIN letter_outgoing_recipients lor ON lor.letter_id = lo.id
|
INNER JOIN letter_outgoing_recipients lor ON lor.letter_id = lo.id
|
||||||
WHERE lo.deleted_at IS NULL AND lor.user_id = ?
|
WHERE lo.deleted_at IS NULL AND lor.user_id = ?
|
||||||
|
|||||||
@ -84,7 +84,7 @@ func (s *AnalyticsServiceImpl) GetDashboard(ctx context.Context, req *contract.A
|
|||||||
response.DepartmentStats = s.mapDepartmentStats(deptData)
|
response.DepartmentStats = s.mapDepartmentStats(deptData)
|
||||||
|
|
||||||
// Get monthly trend (last 12 months)
|
// Get monthly trend (last 12 months)
|
||||||
monthlyData, err := s.analyticsRepo.GetMonthlyTrend(ctx, 12)
|
monthlyData, err := s.analyticsRepo.GetMonthlyTrendByUserID(ctx, userID, 12)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user