Files
boc/backend/repository/hr.go
T

175 lines
5.4 KiB
Go
Raw Normal View History

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)
}