update analytic
This commit is contained in:
parent
c8ea680e05
commit
490aa19840
@ -3,6 +3,8 @@ package repository
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -320,7 +322,10 @@ func (r *AnalyticsRepository) GetDepartmentStats(ctx context.Context, startDate,
|
|||||||
db := DBFromContext(ctx, r.db)
|
db := DBFromContext(ctx, r.db)
|
||||||
var results []map[string]interface{}
|
var results []map[string]interface{}
|
||||||
|
|
||||||
// First try using summary table for better performance
|
// Format tanggal untuk logging
|
||||||
|
log.Printf("GetDepartmentStats called with startDate: %v, endDate: %v", startDate, endDate)
|
||||||
|
|
||||||
|
// Try summary table first
|
||||||
query := `
|
query := `
|
||||||
SELECT
|
SELECT
|
||||||
d.id as department_id,
|
d.id as department_id,
|
||||||
@ -332,67 +337,128 @@ func (r *AnalyticsRepository) GetDepartmentStats(ctx context.Context, startDate,
|
|||||||
COALESCE(AVG(dls.avg_response_hours), 0) as avg_response_time,
|
COALESCE(AVG(dls.avg_response_hours), 0) as avg_response_time,
|
||||||
COALESCE(AVG(dls.completion_rate), 0) as completion_rate
|
COALESCE(AVG(dls.completion_rate), 0) as completion_rate
|
||||||
FROM departments d
|
FROM departments d
|
||||||
LEFT JOIN department_letter_summary dls ON dls.department_id = d.id
|
LEFT JOIN department_letter_summary dls ON dls.department_id = d.id`
|
||||||
WHERE 1=1
|
|
||||||
%s
|
var conditions []string
|
||||||
GROUP BY d.id, d.name, d.code
|
var args []interface{}
|
||||||
ORDER BY (COALESCE(SUM(dls.incoming_count), 0) + COALESCE(SUM(dls.outgoing_count), 0)) DESC
|
|
||||||
`
|
|
||||||
|
|
||||||
dateFilter := ""
|
|
||||||
if !startDate.IsZero() {
|
if !startDate.IsZero() {
|
||||||
dateFilter += fmt.Sprintf(" AND dls.summary_date >= '%s'", startDate.Format("2006-01-02"))
|
conditions = append(conditions, "dls.summary_date >= ?")
|
||||||
|
args = append(args, startDate.Format("2006-01-02"))
|
||||||
}
|
}
|
||||||
if !endDate.IsZero() {
|
if !endDate.IsZero() {
|
||||||
dateFilter += fmt.Sprintf(" AND dls.summary_date <= '%s'", endDate.Format("2006-01-02"))
|
conditions = append(conditions, "dls.summary_date <= ?")
|
||||||
|
args = append(args, endDate.Format("2006-01-02"))
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt.Sprintf(query, dateFilter)
|
if len(conditions) > 0 {
|
||||||
|
query += " WHERE " + strings.Join(conditions, " AND ")
|
||||||
|
}
|
||||||
|
|
||||||
if err := db.Raw(query).Scan(&results).Error; err != nil {
|
query += `
|
||||||
|
GROUP BY d.id, d.name, d.code
|
||||||
|
ORDER BY (COALESCE(SUM(dls.incoming_count), 0) + COALESCE(SUM(dls.outgoing_count), 0)) DESC`
|
||||||
|
|
||||||
|
log.Printf("Summary query: %s, args: %v", query, args)
|
||||||
|
|
||||||
|
if err := db.Raw(query, args...).Scan(&results).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no results from summary table, fall back to direct query
|
// Check if summary table has data for this period
|
||||||
if len(results) == 0 {
|
var summaryCount int64
|
||||||
|
checkQuery := "SELECT COUNT(*) FROM department_letter_summary WHERE 1=1"
|
||||||
|
checkArgs := []interface{}{}
|
||||||
|
|
||||||
|
if !startDate.IsZero() {
|
||||||
|
checkQuery += " AND summary_date >= ?"
|
||||||
|
checkArgs = append(checkArgs, startDate.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
if !endDate.IsZero() {
|
||||||
|
checkQuery += " AND summary_date <= ?"
|
||||||
|
checkArgs = append(checkArgs, endDate.Format("2006-01-02"))
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Raw(checkQuery, checkArgs...).Scan(&summaryCount)
|
||||||
|
log.Printf("Summary count: %d", summaryCount)
|
||||||
|
|
||||||
|
// If no summary data exists for this period, fall back to direct query
|
||||||
|
if summaryCount == 0 {
|
||||||
|
log.Println("Using fallback query (no summary data)")
|
||||||
|
|
||||||
|
// Use CTE for better performance
|
||||||
fallbackQuery := `
|
fallbackQuery := `
|
||||||
|
WITH filtered_incoming AS (
|
||||||
|
SELECT
|
||||||
|
li.id,
|
||||||
|
li.created_at,
|
||||||
|
li.updated_at,
|
||||||
|
lir.recipient_department_id
|
||||||
|
FROM letters_incoming li
|
||||||
|
INNER JOIN letter_incoming_recipients lir ON lir.letter_id = li.id
|
||||||
|
WHERE li.deleted_at IS NULL`
|
||||||
|
|
||||||
|
var fallbackArgs []interface{}
|
||||||
|
|
||||||
|
if !startDate.IsZero() {
|
||||||
|
fallbackQuery += " AND li.created_at >= ?"
|
||||||
|
fallbackArgs = append(fallbackArgs, startDate)
|
||||||
|
}
|
||||||
|
if !endDate.IsZero() {
|
||||||
|
fallbackQuery += " AND li.created_at <= ?"
|
||||||
|
fallbackArgs = append(fallbackArgs, endDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
fallbackQuery += `
|
||||||
|
),
|
||||||
|
filtered_outgoing AS (
|
||||||
|
SELECT
|
||||||
|
lo.id,
|
||||||
|
lo.status,
|
||||||
|
lo.created_at,
|
||||||
|
lo.updated_at,
|
||||||
|
lor.department_id
|
||||||
|
FROM letters_outgoing lo
|
||||||
|
INNER JOIN letter_outgoing_recipients lor ON lor.letter_id = lo.id
|
||||||
|
WHERE lo.deleted_at IS NULL`
|
||||||
|
|
||||||
|
if !startDate.IsZero() {
|
||||||
|
fallbackQuery += " AND lo.created_at >= ?"
|
||||||
|
fallbackArgs = append(fallbackArgs, startDate)
|
||||||
|
}
|
||||||
|
if !endDate.IsZero() {
|
||||||
|
fallbackQuery += " AND lo.created_at <= ?"
|
||||||
|
fallbackArgs = append(fallbackArgs, endDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
fallbackQuery += `
|
||||||
|
)
|
||||||
SELECT
|
SELECT
|
||||||
d.id as department_id,
|
d.id as department_id,
|
||||||
d.name as department_name,
|
d.name as department_name,
|
||||||
d.code as department_code,
|
d.code as department_code,
|
||||||
COUNT(DISTINCT lir.letter_id) as incoming_count,
|
COUNT(DISTINCT fi.id) as incoming_count,
|
||||||
COUNT(DISTINCT lor.letter_id) as outgoing_count,
|
COUNT(DISTINCT fo.id) as outgoing_count,
|
||||||
COUNT(DISTINCT CASE WHEN lo.status = 'pending_approval' THEN lo.id END) as pending_count,
|
COUNT(DISTINCT CASE WHEN fo.status = 'pending_approval' THEN fo.id END) as pending_count,
|
||||||
COALESCE(AVG(CASE
|
COALESCE(AVG(CASE
|
||||||
WHEN lo.status IN ('approved', 'sent', 'archived')
|
WHEN fo.status IN ('approved', 'sent', 'archived')
|
||||||
THEN EXTRACT(EPOCH FROM (lo.updated_at - lo.created_at))/3600
|
THEN EXTRACT(EPOCH FROM (fo.updated_at - fo.created_at))/3600
|
||||||
END), 0) as avg_response_time,
|
END), 0) as avg_response_time,
|
||||||
CASE
|
CASE
|
||||||
WHEN COUNT(DISTINCT lo.id) > 0
|
WHEN COUNT(DISTINCT fo.id) > 0
|
||||||
THEN ROUND(COUNT(DISTINCT CASE WHEN lo.status IN ('sent', 'archived') THEN lo.id END) * 100.0 / COUNT(DISTINCT lo.id), 2)
|
THEN ROUND(COUNT(DISTINCT CASE WHEN fo.status IN ('sent', 'archived') THEN fo.id END) * 100.0 / COUNT(DISTINCT fo.id), 2)
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END as completion_rate
|
END as completion_rate
|
||||||
FROM departments d
|
FROM departments d
|
||||||
LEFT JOIN letter_incoming_recipients lir ON lir.recipient_department_id = d.id
|
LEFT JOIN filtered_incoming fi ON fi.recipient_department_id = d.id
|
||||||
LEFT JOIN letter_outgoing_recipients lor ON lor.department_id = d.id
|
LEFT JOIN filtered_outgoing fo ON fo.department_id = d.id
|
||||||
LEFT JOIN letters_outgoing lo ON lo.id = lor.letter_id AND lo.deleted_at IS NULL
|
|
||||||
WHERE 1=1
|
|
||||||
%s
|
|
||||||
GROUP BY d.id, d.name, d.code
|
GROUP BY d.id, d.name, d.code
|
||||||
ORDER BY (COUNT(DISTINCT lir.letter_id) + COUNT(DISTINCT lor.letter_id)) DESC
|
ORDER BY (COUNT(DISTINCT fi.id) + COUNT(DISTINCT fo.id)) DESC`
|
||||||
`
|
|
||||||
|
|
||||||
fallbackDateFilter := ""
|
log.Printf("Fallback query: %s", fallbackQuery)
|
||||||
if !startDate.IsZero() {
|
log.Printf("Fallback args: %v", fallbackArgs)
|
||||||
fallbackDateFilter += fmt.Sprintf(" AND (lo.created_at >= '%s' OR lo.created_at IS NULL)", startDate.Format("2006-01-02"))
|
|
||||||
}
|
|
||||||
if !endDate.IsZero() {
|
|
||||||
fallbackDateFilter += fmt.Sprintf(" AND (lo.created_at <= '%s' OR lo.created_at IS NULL)", endDate.Format("2006-01-02"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fallbackQuery = fmt.Sprintf(fallbackQuery, fallbackDateFilter)
|
if err := db.Raw(fallbackQuery, fallbackArgs...).Scan(&results).Error; err != nil {
|
||||||
|
|
||||||
if err := db.Raw(fallbackQuery).Scan(&results).Error; err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user