update dashboard analytic
This commit is contained in:
parent
ea980f8cf7
commit
f391b6d853
@ -36,13 +36,13 @@ func (r *AnalyticsRepository) GetLetterSummaryStats(ctx context.Context, startDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
TotalIncoming int64 `gorm:"column:total_incoming"`
|
TotalIncoming int64 `gorm:"column:total_incoming"`
|
||||||
TotalOutgoing int64 `gorm:"column:total_outgoing"`
|
TotalOutgoing int64 `gorm:"column:total_outgoing"`
|
||||||
PendingOutgoing int64 `gorm:"column:pending_outgoing"`
|
PendingOutgoing int64 `gorm:"column:pending_outgoing"`
|
||||||
ApprovedOutgoing int64 `gorm:"column:approved_outgoing"`
|
ApprovedOutgoing int64 `gorm:"column:approved_outgoing"`
|
||||||
RejectedOutgoing int64 `gorm:"column:rejected_outgoing"`
|
RejectedOutgoing int64 `gorm:"column:rejected_outgoing"`
|
||||||
AvgResponseHours float64 `gorm:"column:avg_response_hours"`
|
AvgResponseHours float64 `gorm:"column:avg_response_hours"`
|
||||||
CompletionRate float64 `gorm:"column:completion_rate"`
|
CompletionRate float64 `gorm:"column:completion_rate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
query.Select(`
|
query.Select(`
|
||||||
@ -75,14 +75,14 @@ func (r *AnalyticsRepository) GetLetterSummaryStats(ctx context.Context, startDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result struct {
|
var result struct {
|
||||||
TotalIncoming int64 `gorm:"column:total_incoming"`
|
TotalIncoming int64 `gorm:"column:total_incoming"`
|
||||||
TotalOutgoing int64 `gorm:"column:total_outgoing"`
|
TotalOutgoing int64 `gorm:"column:total_outgoing"`
|
||||||
TotalPending int64 `gorm:"column:total_pending"`
|
TotalPending int64 `gorm:"column:total_pending"`
|
||||||
TotalApproved int64 `gorm:"column:total_approved"`
|
TotalApproved int64 `gorm:"column:total_approved"`
|
||||||
TotalRejected int64 `gorm:"column:total_rejected"`
|
TotalRejected int64 `gorm:"column:total_rejected"`
|
||||||
TotalArchived int64 `gorm:"column:total_archived"`
|
TotalArchived int64 `gorm:"column:total_archived"`
|
||||||
TotalSent int64 `gorm:"column:total_sent"`
|
TotalSent int64 `gorm:"column:total_sent"`
|
||||||
AvgProcessing float64 `gorm:"column:avg_processing"`
|
AvgProcessing float64 `gorm:"column:avg_processing"`
|
||||||
}
|
}
|
||||||
|
|
||||||
query.Select(`
|
query.Select(`
|
||||||
@ -132,16 +132,21 @@ func (r *AnalyticsRepository) GetLetterSummaryStats(ctx context.Context, startDa
|
|||||||
outgoingQuery = outgoingQuery.
|
outgoingQuery = outgoingQuery.
|
||||||
Joins("LEFT JOIN letter_outgoing_recipients ON letter_outgoing_recipients.letter_id = letters_outgoing.id").
|
Joins("LEFT JOIN letter_outgoing_recipients ON letter_outgoing_recipients.letter_id = letters_outgoing.id").
|
||||||
Where("letter_outgoing_recipients.user_id = ?", *userID)
|
Where("letter_outgoing_recipients.user_id = ?", *userID)
|
||||||
|
incomingQuery = incomingQuery.
|
||||||
|
Joins("LEFT JOIN letter_incoming_recipients ON letter_incoming_recipients.letter_id = letters_incoming.id").
|
||||||
|
Where("letter_incoming_recipients.recipient_user_id = ?", *userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[DEBUG] userId analitycs: %v\n", userID)
|
||||||
|
|
||||||
// Count incoming letters
|
// Count incoming letters
|
||||||
var totalIncoming int64
|
var totalIncoming int64
|
||||||
incomingQuery.Count(&totalIncoming)
|
incomingQuery.Distinct("letters_incoming.id").Count(&totalIncoming)
|
||||||
stats["total_incoming"] = totalIncoming
|
stats["total_incoming"] = totalIncoming
|
||||||
|
|
||||||
// Count outgoing letters
|
// Count outgoing letters
|
||||||
var totalOutgoing int64
|
var totalOutgoing int64
|
||||||
outgoingQuery.Count(&totalOutgoing)
|
outgoingQuery.Distinct("letters_outgoing.id").Count(&totalOutgoing)
|
||||||
stats["total_outgoing"] = totalOutgoing
|
stats["total_outgoing"] = totalOutgoing
|
||||||
|
|
||||||
// Count by status - need to clone query for each count
|
// Count by status - need to clone query for each count
|
||||||
@ -713,6 +718,66 @@ func (r *AnalyticsRepository) GetDailyActivity(ctx context.Context, days int) ([
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *AnalyticsRepository) GetDailyActivityByUserID(ctx context.Context, userID *uuid.UUID, days int) ([]map[string]interface{}, error) {
|
||||||
|
db := DBFromContext(ctx, r.db)
|
||||||
|
var results []map[string]interface{}
|
||||||
|
|
||||||
|
query := `
|
||||||
|
WITH daily_data AS (
|
||||||
|
SELECT
|
||||||
|
DATE(created_at) as date,
|
||||||
|
TO_CHAR(created_at, 'Day') as day_of_week,
|
||||||
|
COUNT(CASE WHEN type = 'incoming' THEN 1 END) as incoming_count,
|
||||||
|
COUNT(CASE WHEN type = 'outgoing' THEN 1 END) as outgoing_count,
|
||||||
|
0 as approved_count,
|
||||||
|
0 as rejected_count
|
||||||
|
FROM (
|
||||||
|
SELECT li.created_at, 'incoming' as type
|
||||||
|
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 = ?
|
||||||
|
UNION ALL
|
||||||
|
SELECT lo.created_at, 'outgoing' as type
|
||||||
|
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 = ?
|
||||||
|
) combined
|
||||||
|
WHERE created_at >= CURRENT_DATE - INTERVAL '%d days'
|
||||||
|
GROUP BY DATE(created_at), TO_CHAR(created_at, 'Day')
|
||||||
|
),
|
||||||
|
approval_data AS (
|
||||||
|
SELECT
|
||||||
|
DATE(acted_at) as date,
|
||||||
|
COUNT(CASE WHEN status = 'approved' THEN 1 END) as approved_count,
|
||||||
|
COUNT(CASE WHEN status = 'rejected' THEN 1 END) as rejected_count
|
||||||
|
FROM letter_outgoing_approvals
|
||||||
|
WHERE acted_at IS NOT NULL
|
||||||
|
AND acted_at >= CURRENT_DATE - INTERVAL '%d days'
|
||||||
|
AND approver_id = ?
|
||||||
|
GROUP BY DATE(acted_at)
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
d.date,
|
||||||
|
d.day_of_week,
|
||||||
|
d.incoming_count,
|
||||||
|
d.outgoing_count,
|
||||||
|
COALESCE(a.approved_count, 0) as approved_count,
|
||||||
|
COALESCE(a.rejected_count, 0) as rejected_count
|
||||||
|
FROM daily_data d
|
||||||
|
LEFT JOIN approval_data a ON a.date = d.date
|
||||||
|
ORDER BY d.date DESC
|
||||||
|
LIMIT %d
|
||||||
|
`
|
||||||
|
|
||||||
|
query = fmt.Sprintf(query, days, days, days)
|
||||||
|
|
||||||
|
if err := db.Raw(query, userID, userID, userID).Scan(&results).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetResponseTimeStats gets response time statistics
|
// GetResponseTimeStats gets response time statistics
|
||||||
func (r *AnalyticsRepository) GetResponseTimeStats(ctx context.Context, startDate, endDate time.Time) (map[string]interface{}, error) {
|
func (r *AnalyticsRepository) GetResponseTimeStats(ctx context.Context, startDate, endDate time.Time) (map[string]interface{}, error) {
|
||||||
db := DBFromContext(ctx, r.db)
|
db := DBFromContext(ctx, r.db)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"eslogad-be/internal/appcontext"
|
"eslogad-be/internal/appcontext"
|
||||||
@ -61,6 +62,7 @@ func (s *AnalyticsServiceImpl) GetDashboard(ctx context.Context, req *contract.A
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fmt.Printf("[DEBUG] summaryData: %v\n", summaryData)
|
||||||
response.Summary = s.mapSummaryStats(summaryData)
|
response.Summary = s.mapSummaryStats(summaryData)
|
||||||
|
|
||||||
// Calculate growth metrics
|
// Calculate growth metrics
|
||||||
@ -99,7 +101,7 @@ func (s *AnalyticsServiceImpl) GetDashboard(ctx context.Context, req *contract.A
|
|||||||
response.InstitutionStats = s.mapInstitutionStats(instData)
|
response.InstitutionStats = s.mapInstitutionStats(instData)
|
||||||
|
|
||||||
// Get daily activity (last 7 days)
|
// Get daily activity (last 7 days)
|
||||||
dailyData, err := s.analyticsRepo.GetDailyActivity(ctx, 7)
|
dailyData, err := s.analyticsRepo.GetDailyActivityByUserID(ctx, userID, 7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user