309 lines
12 KiB
Go
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})
|
|
}
|