175 lines
5.4 KiB
Go
175 lines
5.4 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"database/sql"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Employee represents a company employee
|
||
|
|
type Employee struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
Name string `json:"name"`
|
||
|
|
Email string `json:"email"`
|
||
|
|
Phone string `json:"phone"`
|
||
|
|
Department string `json:"department"`
|
||
|
|
Position string `json:"position"`
|
||
|
|
StartDate time.Time `json:"start_date"`
|
||
|
|
Status string `json:"status"`
|
||
|
|
CreatedAt time.Time `json:"created_at"`
|
||
|
|
UpdatedAt time.Time `json:"updated_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Leave represents a leave request
|
||
|
|
type Leave struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
EmployeeID string `json:"employee_id"`
|
||
|
|
Type string `json:"type"`
|
||
|
|
StartDate time.Time `json:"start_date"`
|
||
|
|
EndDate time.Time `json:"end_date"`
|
||
|
|
Status string `json:"status"`
|
||
|
|
CreatedAt time.Time `json:"created_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Timesheet represents a time entry
|
||
|
|
type Timesheet struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
EmployeeID string `json:"employee_id"`
|
||
|
|
ProjectID *string `json:"project_id"`
|
||
|
|
Date time.Time `json:"date"`
|
||
|
|
Hours float64 `json:"hours"`
|
||
|
|
Description string `json:"description"`
|
||
|
|
Status string `json:"status"`
|
||
|
|
CreatedAt time.Time `json:"created_at"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// HRRepository handles all HR-related database operations
|
||
|
|
type HRRepository struct {
|
||
|
|
db *sql.DB
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewHRRepository(db *sql.DB) *HRRepository {
|
||
|
|
return &HRRepository{db: db}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListEmployees returns all employees
|
||
|
|
func (r *HRRepository) ListEmployees(ctx context.Context) ([]Employee, error) {
|
||
|
|
rows, err := r.db.QueryContext(ctx, `
|
||
|
|
SELECT id, name, email, phone, department, position, start_date, status, created_at, updated_at
|
||
|
|
FROM boc_employees
|
||
|
|
ORDER BY name
|
||
|
|
`)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var employees []Employee
|
||
|
|
for rows.Next() {
|
||
|
|
var e Employee
|
||
|
|
if err := rows.Scan(&e.ID, &e.Name, &e.Email, &e.Phone, &e.Department, &e.Position, &e.StartDate, &e.Status, &e.CreatedAt, &e.UpdatedAt); err != nil {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
employees = append(employees, e)
|
||
|
|
}
|
||
|
|
return employees, rows.Err()
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetEmployee returns a single employee by ID
|
||
|
|
func (r *HRRepository) GetEmployee(ctx context.Context, id string) (*Employee, error) {
|
||
|
|
var e Employee
|
||
|
|
err := r.db.QueryRowContext(ctx, `
|
||
|
|
SELECT id, name, email, phone, department, position, start_date, status, created_at, updated_at
|
||
|
|
FROM boc_employees
|
||
|
|
WHERE id = $1
|
||
|
|
`, id).Scan(&e.ID, &e.Name, &e.Email, &e.Phone, &e.Department, &e.Position, &e.StartDate, &e.Status, &e.CreatedAt, &e.UpdatedAt)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &e, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateEmployee creates a new employee
|
||
|
|
func (r *HRRepository) CreateEmployee(ctx context.Context, e *Employee) error {
|
||
|
|
return r.db.QueryRowContext(ctx, `
|
||
|
|
INSERT INTO boc_employees (name, email, phone, department, position, start_date, status)
|
||
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||
|
|
RETURNING id, created_at, updated_at
|
||
|
|
`, e.Name, e.Email, e.Phone, e.Department, e.Position, e.StartDate, e.Status).Scan(&e.ID, &e.CreatedAt, &e.UpdatedAt)
|
||
|
|
}
|
||
|
|
|
||
|
|
// UpdateEmployee updates an existing employee
|
||
|
|
func (r *HRRepository) UpdateEmployee(ctx context.Context, id string, e *Employee) error {
|
||
|
|
_, err := r.db.ExecContext(ctx, `
|
||
|
|
UPDATE boc_employees
|
||
|
|
SET name = $1, email = $2, phone = $3, department = $4, position = $5, start_date = $6, status = $7, updated_at = NOW()
|
||
|
|
WHERE id = $8
|
||
|
|
`, e.Name, e.Email, e.Phone, e.Department, e.Position, e.StartDate, e.Status, id)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListLeaves returns all leave requests
|
||
|
|
func (r *HRRepository) ListLeaves(ctx context.Context) ([]Leave, error) {
|
||
|
|
rows, err := r.db.QueryContext(ctx, `
|
||
|
|
SELECT id, employee_id, type, start_date, end_date, status, created_at
|
||
|
|
FROM boc_leaves
|
||
|
|
ORDER BY start_date DESC
|
||
|
|
`)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var leaves []Leave
|
||
|
|
for rows.Next() {
|
||
|
|
var l Leave
|
||
|
|
if err := rows.Scan(&l.ID, &l.EmployeeID, &l.Type, &l.StartDate, &l.EndDate, &l.Status, &l.CreatedAt); err != nil {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
leaves = append(leaves, l)
|
||
|
|
}
|
||
|
|
return leaves, rows.Err()
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateLeave creates a new leave request
|
||
|
|
func (r *HRRepository) CreateLeave(ctx context.Context, l *Leave) error {
|
||
|
|
return r.db.QueryRowContext(ctx, `
|
||
|
|
INSERT INTO boc_leaves (employee_id, type, start_date, end_date, status)
|
||
|
|
VALUES ($1, $2, $3, $4, $5)
|
||
|
|
RETURNING id, created_at
|
||
|
|
`, l.EmployeeID, l.Type, l.StartDate, l.EndDate, l.Status).Scan(&l.ID, &l.CreatedAt)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListTimesheets returns all timesheet entries
|
||
|
|
func (r *HRRepository) ListTimesheets(ctx context.Context) ([]Timesheet, error) {
|
||
|
|
rows, err := r.db.QueryContext(ctx, `
|
||
|
|
SELECT id, employee_id, project_id, date, hours, description, status, created_at
|
||
|
|
FROM boc_timesheets
|
||
|
|
ORDER BY date DESC
|
||
|
|
LIMIT 100
|
||
|
|
`)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
var timesheets []Timesheet
|
||
|
|
for rows.Next() {
|
||
|
|
var t Timesheet
|
||
|
|
if err := rows.Scan(&t.ID, &t.EmployeeID, &t.ProjectID, &t.Date, &t.Hours, &t.Description, &t.Status, &t.CreatedAt); err != nil {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
timesheets = append(timesheets, t)
|
||
|
|
}
|
||
|
|
return timesheets, rows.Err()
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateTimesheet creates a new timesheet entry
|
||
|
|
func (r *HRRepository) CreateTimesheet(ctx context.Context, t *Timesheet) error {
|
||
|
|
return r.db.QueryRowContext(ctx, `
|
||
|
|
INSERT INTO boc_timesheets (employee_id, project_id, date, hours, description, status)
|
||
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
||
|
|
RETURNING id, created_at
|
||
|
|
`, t.EmployeeID, t.ProjectID, t.Date, t.Hours, t.Description, t.Status).Scan(&t.ID, &t.CreatedAt)
|
||
|
|
}
|