Projeto bot pontos
This commit is contained in:
93
backend/internal/adapters/postgres/schedules.go
Normal file
93
backend/internal/adapters/postgres/schedules.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"botpontos/internal/domain"
|
||||
)
|
||||
|
||||
func scheduleCols(p string) string {
|
||||
return fmt.Sprintf(`%[1]suser_id, %[1]slunch_minutes, %[1]sdaily_work_minutes, %[1]sentrada2_lead_minutes,
|
||||
%[1]ssaida2_lead_minutes,
|
||||
to_char(%[1]squery_window_start, 'HH24:MI'), to_char(%[1]squery_window_end, 'HH24:MI'),
|
||||
to_char(%[1]sday_check_deadline, 'HH24:MI'), to_char(%[1]sno_points_recheck_until, 'HH24:MI')`, p)
|
||||
}
|
||||
|
||||
type scheduleScan struct {
|
||||
s domain.WorkSchedule
|
||||
start, end, deadline, recheckUntil *string
|
||||
}
|
||||
|
||||
func (s *scheduleScan) dest() []any {
|
||||
return []any{&s.s.UserID, &s.s.LunchMinutes, &s.s.DailyWorkMinutes, &s.s.Entrada2LeadMinutes,
|
||||
&s.s.Saida2LeadMinutes, &s.start, &s.end, &s.deadline, &s.recheckUntil}
|
||||
}
|
||||
|
||||
func (s *scheduleScan) result() (domain.WorkSchedule, error) {
|
||||
out := s.s
|
||||
if s.start == nil || s.end == nil || s.deadline == nil || s.recheckUntil == nil {
|
||||
return out, nil
|
||||
}
|
||||
var w domain.QueryWindow
|
||||
var err error
|
||||
if w.Start, err = domain.ParseClock(*s.start); err != nil {
|
||||
return out, err
|
||||
}
|
||||
if w.End, err = domain.ParseClock(*s.end); err != nil {
|
||||
return out, err
|
||||
}
|
||||
if w.DayCheckDeadline, err = domain.ParseClock(*s.deadline); err != nil {
|
||||
return out, err
|
||||
}
|
||||
if w.NoPointsRecheckUntil, err = domain.ParseClock(*s.recheckUntil); err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.Window = &w
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetSchedule devolve a jornada do usuário ou a padrão, se ainda não houver linha.
|
||||
func (s *Store) GetSchedule(ctx context.Context, userID int64) (domain.WorkSchedule, error) {
|
||||
var ss scheduleScan
|
||||
err := s.pool.QueryRow(ctx, `SELECT `+scheduleCols("")+` FROM work_schedules WHERE user_id = $1`, userID).Scan(ss.dest()...)
|
||||
if err != nil {
|
||||
if mapErr(err) == domain.ErrNotFound {
|
||||
return domain.DefaultSchedule(userID), nil
|
||||
}
|
||||
return domain.WorkSchedule{}, err
|
||||
}
|
||||
return ss.result()
|
||||
}
|
||||
|
||||
func (s *Store) SaveSchedule(ctx context.Context, sch domain.WorkSchedule) error {
|
||||
var start, end, deadline, recheck *string
|
||||
if w := sch.Window; w != nil {
|
||||
start, end = strPtr(w.Start.String()), strPtr(w.End.String())
|
||||
deadline, recheck = strPtr(w.DayCheckDeadline.String()), strPtr(w.NoPointsRecheckUntil.String())
|
||||
}
|
||||
_, err := s.pool.Exec(ctx, `
|
||||
INSERT INTO work_schedules (user_id, lunch_minutes, daily_work_minutes, entrada2_lead_minutes, saida2_lead_minutes,
|
||||
query_window_start, query_window_end, day_check_deadline, no_points_recheck_until)
|
||||
VALUES ($1, $2, $3, $4, $5, $6::text::time, $7::text::time, $8::text::time, $9::text::time)
|
||||
ON CONFLICT (user_id) DO UPDATE SET
|
||||
lunch_minutes = EXCLUDED.lunch_minutes,
|
||||
daily_work_minutes = EXCLUDED.daily_work_minutes,
|
||||
entrada2_lead_minutes = EXCLUDED.entrada2_lead_minutes,
|
||||
saida2_lead_minutes = EXCLUDED.saida2_lead_minutes,
|
||||
query_window_start = EXCLUDED.query_window_start,
|
||||
query_window_end = EXCLUDED.query_window_end,
|
||||
day_check_deadline = EXCLUDED.day_check_deadline,
|
||||
no_points_recheck_until = EXCLUDED.no_points_recheck_until`,
|
||||
sch.UserID, sch.LunchMinutes, sch.DailyWorkMinutes, sch.Entrada2LeadMinutes, sch.Saida2LeadMinutes,
|
||||
start, end, deadline, recheck)
|
||||
return mapErr(err)
|
||||
}
|
||||
|
||||
func (s *Store) CountCustomWindows(ctx context.Context) (int, error) {
|
||||
var n int
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
SELECT count(*) FROM work_schedules ws JOIN users u ON u.id = ws.user_id
|
||||
WHERE ws.query_window_start IS NOT NULL AND u.status = 'active'`).Scan(&n)
|
||||
return n, err
|
||||
}
|
||||
Reference in New Issue
Block a user