Files
satusehat-service/exemple/service.go
T
2026-04-14 01:23:34 +00:00

62 lines
1.6 KiB
Go

package report
import (
"context"
"service/pkg/errors"
)
type Service interface {
GenerateCrossDBReport(ctx context.Context) ([]CombinedReport, error)
}
type service struct {
repo Repository
}
func NewService(repo Repository) Service {
return &service{repo: repo}
}
func (s *service) GenerateCrossDBReport(ctx context.Context) ([]CombinedReport, error) {
// 1. Ambil data master karyawan dari PostgreSQL
employees, err := s.repo.GetEmployeesFromPostgres(ctx)
if err != nil {
return nil, errors.InternalError().Message("Failed to fetch employees from Postgres").Cause(err).Build()
}
if len(employees) == 0 {
return []CombinedReport{}, nil
}
// 2. Ekstrak ID karyawan untuk klausa IN (?) di MySQL
var empIDs []int64
for _, emp := range employees {
empIDs = append(empIDs, emp.ID)
}
// 3. Ambil data transaksi kehadiran dari MySQL menggunakan list ID di atas
attendances, err := s.repo.GetAttendancesFromMySQL(ctx, empIDs)
if err != nil {
return nil, errors.InternalError().Message("Failed to fetch attendances from MySQL").Cause(err).Build()
}
// 4. Proses In-Memory Join (Mapping)
// Kelompokkan attendance berdasarkan EmployeeID agar pencarian cepat O(1)
attendanceMap := make(map[int64][]Attendance)
for _, att := range attendances {
attendanceMap[att.EmployeeID] = append(attendanceMap[att.EmployeeID], att)
}
// Gabungkan data
var reports []CombinedReport
for _, emp := range employees {
reports = append(reports, CombinedReport{
EmployeeName: emp.Name,
Department: emp.Department,
Attendances: attendanceMap[emp.ID], // Ambil relasinya dari memory map
})
}
return reports, nil
}