Files
workorders/internal/api/handlers/registry.go
T

309 lines
12 KiB
Go

package handlers
import (
"net/http"
"github.com/jmoiron/sqlx"
"workorders/internal/model"
)
type RegistryHandler struct{ db *sqlx.DB }
func NewRegistryHandler(db *sqlx.DB) *RegistryHandler { return &RegistryHandler{db: db} }
// ── People ────────────────────────────────────────────────────────────────────
func (h *RegistryHandler) ListPeople(w http.ResponseWriter, r *http.Request) {
search := r.URL.Query().Get("search")
all := r.URL.Query().Get("all") == "1"
var rows []model.RegistryPerson
var err error
pat := "%" + search + "%"
if all && search != "" {
err = h.db.Select(&rows, `SELECT id,name,role,email,phone,active FROM resource_people WHERE (name LIKE @p1 OR email LIKE @p1 OR role LIKE @p1) ORDER BY name`, pat)
} else if all {
err = h.db.Select(&rows, `SELECT id,name,role,email,phone,active FROM resource_people ORDER BY name`)
} else if search != "" {
err = h.db.Select(&rows, `SELECT id,name,role,email,phone,active FROM resource_people WHERE active=1 AND (name LIKE @p1 OR email LIKE @p1 OR role LIKE @p1) ORDER BY name`, pat)
} else {
err = h.db.Select(&rows, `SELECT id,name,role,email,phone,active FROM resource_people WHERE active=1 ORDER BY name`)
}
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
if rows == nil {
rows = []model.RegistryPerson{}
}
respond(w, http.StatusOK, rows)
}
func (h *RegistryHandler) CreatePerson(w http.ResponseWriter, r *http.Request) {
var body model.RegistryPerson
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
var id int
err := h.db.QueryRow(`INSERT INTO resource_people (name,role,email,phone) OUTPUT INSERTED.id VALUES (@p1,@p2,@p3,@p4)`,
body.Name, body.Role, body.Email, body.Phone).Scan(&id)
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
var person model.RegistryPerson
h.db.Get(&person, `SELECT id,name,role,email,phone,active FROM resource_people WHERE id=@p1`, id)
respond(w, http.StatusCreated, person)
}
func (h *RegistryHandler) UpdatePerson(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
var body model.RegistryPerson
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
h.db.Exec(`UPDATE resource_people SET name=@p1,role=@p2,email=@p3,phone=@p4,active=@p5 WHERE id=@p6`,
body.Name, body.Role, body.Email, body.Phone, body.Active, id)
var person model.RegistryPerson
h.db.Get(&person, `SELECT id,name,role,email,phone,active FROM resource_people WHERE id=@p1`, id)
respond(w, http.StatusOK, person)
}
func (h *RegistryHandler) DeletePerson(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
h.db.Exec(`UPDATE resource_people SET active=0 WHERE id=@p1`, id)
respond(w, http.StatusOK, map[string]any{"deactivated": id})
}
// ── Vehicles ──────────────────────────────────────────────────────────────────
func (h *RegistryHandler) ListVehicles(w http.ResponseWriter, r *http.Request) {
search := r.URL.Query().Get("search")
all := r.URL.Query().Get("all") == "1"
var rows []model.RegistryVehicle
var err error
pat := "%" + search + "%"
if all && search != "" {
err = h.db.Select(&rows, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles WHERE (unit_number LIKE @p1 OR description LIKE @p1 OR vehicle_type LIKE @p1) ORDER BY unit_number`, pat)
} else if all {
err = h.db.Select(&rows, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles ORDER BY unit_number`)
} else if search != "" {
err = h.db.Select(&rows, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles WHERE active=1 AND (unit_number LIKE @p1 OR description LIKE @p1) ORDER BY unit_number`, pat)
} else {
err = h.db.Select(&rows, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles WHERE active=1 ORDER BY unit_number`)
}
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
if rows == nil {
rows = []model.RegistryVehicle{}
}
respond(w, http.StatusOK, rows)
}
func (h *RegistryHandler) CreateVehicle(w http.ResponseWriter, r *http.Request) {
var body model.RegistryVehicle
if err := decode(r, &body); err != nil || body.UnitNumber == "" {
respondError(w, http.StatusBadRequest, "unit_number required")
return
}
var id int
err := h.db.QueryRow(`INSERT INTO resource_vehicles (unit_number,description,vehicle_type) OUTPUT INSERTED.id VALUES (@p1,@p2,@p3)`,
body.UnitNumber, body.Description, body.VehicleType).Scan(&id)
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
var v model.RegistryVehicle
h.db.Get(&v, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles WHERE id=@p1`, id)
respond(w, http.StatusCreated, v)
}
func (h *RegistryHandler) UpdateVehicle(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
var body model.RegistryVehicle
if err := decode(r, &body); err != nil || body.UnitNumber == "" {
respondError(w, http.StatusBadRequest, "unit_number required")
return
}
h.db.Exec(`UPDATE resource_vehicles SET unit_number=@p1,description=@p2,vehicle_type=@p3,active=@p4 WHERE id=@p5`,
body.UnitNumber, body.Description, body.VehicleType, body.Active, id)
var v model.RegistryVehicle
h.db.Get(&v, `SELECT id,unit_number,description,vehicle_type,active FROM resource_vehicles WHERE id=@p1`, id)
respond(w, http.StatusOK, v)
}
func (h *RegistryHandler) DeleteVehicle(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
h.db.Exec(`UPDATE resource_vehicles SET active=0 WHERE id=@p1`, id)
respond(w, http.StatusOK, map[string]any{"deactivated": id})
}
// ── Equipment ─────────────────────────────────────────────────────────────────
func (h *RegistryHandler) ListEquipment(w http.ResponseWriter, r *http.Request) {
search := r.URL.Query().Get("search")
all := r.URL.Query().Get("all") == "1"
var rows []model.RegistryEquipment
var err error
pat := "%" + search + "%"
if all && search != "" {
err = h.db.Select(&rows, `SELECT id,name,asset_tag,category,active FROM resource_equipment WHERE (name LIKE @p1 OR asset_tag LIKE @p1 OR category LIKE @p1) ORDER BY name`, pat)
} else if all {
err = h.db.Select(&rows, `SELECT id,name,asset_tag,category,active FROM resource_equipment ORDER BY name`)
} else if search != "" {
err = h.db.Select(&rows, `SELECT id,name,asset_tag,category,active FROM resource_equipment WHERE active=1 AND (name LIKE @p1 OR asset_tag LIKE @p1) ORDER BY name`, pat)
} else {
err = h.db.Select(&rows, `SELECT id,name,asset_tag,category,active FROM resource_equipment WHERE active=1 ORDER BY name`)
}
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
if rows == nil {
rows = []model.RegistryEquipment{}
}
respond(w, http.StatusOK, rows)
}
func (h *RegistryHandler) CreateEquipment(w http.ResponseWriter, r *http.Request) {
var body model.RegistryEquipment
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
var id int
err := h.db.QueryRow(`INSERT INTO resource_equipment (name,asset_tag,category) OUTPUT INSERTED.id VALUES (@p1,@p2,@p3)`,
body.Name, body.AssetTag, body.Category).Scan(&id)
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
var eq model.RegistryEquipment
h.db.Get(&eq, `SELECT id,name,asset_tag,category,active FROM resource_equipment WHERE id=@p1`, id)
respond(w, http.StatusCreated, eq)
}
func (h *RegistryHandler) UpdateEquipment(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
var body model.RegistryEquipment
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
h.db.Exec(`UPDATE resource_equipment SET name=@p1,asset_tag=@p2,category=@p3,active=@p4 WHERE id=@p5`,
body.Name, body.AssetTag, body.Category, body.Active, id)
var eq model.RegistryEquipment
h.db.Get(&eq, `SELECT id,name,asset_tag,category,active FROM resource_equipment WHERE id=@p1`, id)
respond(w, http.StatusOK, eq)
}
func (h *RegistryHandler) DeleteEquipment(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
h.db.Exec(`UPDATE resource_equipment SET active=0 WHERE id=@p1`, id)
respond(w, http.StatusOK, map[string]any{"deactivated": id})
}
// ── Materials ─────────────────────────────────────────────────────────────────
func (h *RegistryHandler) ListMaterials(w http.ResponseWriter, r *http.Request) {
search := r.URL.Query().Get("search")
all := r.URL.Query().Get("all") == "1"
var rows []model.RegistryMaterial
var err error
pat := "%" + search + "%"
if all && search != "" {
err = h.db.Select(&rows, `SELECT id,name,unit,part_number,active FROM resource_materials WHERE (name LIKE @p1 OR part_number LIKE @p1) ORDER BY name`, pat)
} else if all {
err = h.db.Select(&rows, `SELECT id,name,unit,part_number,active FROM resource_materials ORDER BY name`)
} else if search != "" {
err = h.db.Select(&rows, `SELECT id,name,unit,part_number,active FROM resource_materials WHERE active=1 AND (name LIKE @p1 OR part_number LIKE @p1) ORDER BY name`, pat)
} else {
err = h.db.Select(&rows, `SELECT id,name,unit,part_number,active FROM resource_materials WHERE active=1 ORDER BY name`)
}
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
if rows == nil {
rows = []model.RegistryMaterial{}
}
respond(w, http.StatusOK, rows)
}
func (h *RegistryHandler) CreateMaterial(w http.ResponseWriter, r *http.Request) {
var body model.RegistryMaterial
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
var id int
err := h.db.QueryRow(`INSERT INTO resource_materials (name,unit,part_number) OUTPUT INSERTED.id VALUES (@p1,@p2,@p3)`,
body.Name, body.Unit, body.PartNumber).Scan(&id)
if err != nil {
respondError(w, http.StatusInternalServerError, err.Error())
return
}
var m model.RegistryMaterial
h.db.Get(&m, `SELECT id,name,unit,part_number,active FROM resource_materials WHERE id=@p1`, id)
respond(w, http.StatusCreated, m)
}
func (h *RegistryHandler) UpdateMaterial(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
var body model.RegistryMaterial
if err := decode(r, &body); err != nil || body.Name == "" {
respondError(w, http.StatusBadRequest, "name required")
return
}
h.db.Exec(`UPDATE resource_materials SET name=@p1,unit=@p2,part_number=@p3,active=@p4 WHERE id=@p5`,
body.Name, body.Unit, body.PartNumber, body.Active, id)
var m model.RegistryMaterial
h.db.Get(&m, `SELECT id,name,unit,part_number,active FROM resource_materials WHERE id=@p1`, id)
respond(w, http.StatusOK, m)
}
func (h *RegistryHandler) DeleteMaterial(w http.ResponseWriter, r *http.Request) {
id, err := intParam(r, "id")
if err != nil {
respondError(w, http.StatusBadRequest, "invalid id")
return
}
h.db.Exec(`UPDATE resource_materials SET active=0 WHERE id=@p1`, id)
respond(w, http.StatusOK, map[string]any{"deactivated": id})
}