cmc-sales/go/internal/cmc/handlers/enquiry.go

344 lines
9.3 KiB
Go

package handlers
import (
"database/sql"
"encoding/json"
"net/http"
"strconv"
"time"
"code.springupsoftware.com/cmc/cmc-sales/internal/cmc/db"
"github.com/gorilla/mux"
)
type EnquiryHandler struct {
queries *db.Queries
}
func NewEnquiryHandler(queries *db.Queries) *EnquiryHandler {
return &EnquiryHandler{queries: queries}
}
type CreateEnquiryRequest struct {
Title string `json:"title"`
UserID int32 `json:"user_id"`
CustomerID int32 `json:"customer_id"`
ContactID int32 `json:"contact_id"`
ContactUserID int32 `json:"contact_user_id"`
StateID int32 `json:"state_id"`
CountryID int32 `json:"country_id"`
PrincipleID int32 `json:"principle_id"`
StatusID int32 `json:"status_id"`
Comments string `json:"comments"`
PrincipleCode int32 `json:"principle_code"`
Gst bool `json:"gst"`
BillingAddressID sql.NullInt32 `json:"billing_address_id"`
ShippingAddressID sql.NullInt32 `json:"shipping_address_id"`
Posted bool `json:"posted"`
}
type UpdateEnquiryRequest struct {
Title string `json:"title"`
UserID int32 `json:"user_id"`
CustomerID int32 `json:"customer_id"`
ContactID int32 `json:"contact_id"`
ContactUserID int32 `json:"contact_user_id"`
StateID int32 `json:"state_id"`
CountryID int32 `json:"country_id"`
PrincipleID int32 `json:"principle_id"`
StatusID int32 `json:"status_id"`
Comments string `json:"comments"`
PrincipleCode int32 `json:"principle_code"`
Gst bool `json:"gst"`
BillingAddressID sql.NullInt32 `json:"billing_address_id"`
ShippingAddressID sql.NullInt32 `json:"shipping_address_id"`
Posted bool `json:"posted"`
Submitted sql.NullTime `json:"submitted"`
}
func (h *EnquiryHandler) List(w http.ResponseWriter, r *http.Request) {
page := 1
if p := r.URL.Query().Get("page"); p != "" {
if val, err := strconv.Atoi(p); err == nil && val > 0 {
page = val
}
}
limit := 150 // Same as CakePHP controller
offset := (page - 1) * limit
var enquiries interface{}
var err error
// Check if we want archived enquiries
if r.URL.Query().Get("archived") == "true" {
enquiries, err = h.queries.ListArchivedEnquiries(r.Context(), db.ListArchivedEnquiriesParams{
Limit: int32(limit),
Offset: int32(offset),
})
} else {
enquiries, err = h.queries.ListEnquiries(r.Context(), db.ListEnquiriesParams{
Limit: int32(limit),
Offset: int32(offset),
})
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(enquiries)
}
func (h *EnquiryHandler) Get(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
enquiry, err := h.queries.GetEnquiry(r.Context(), int32(id))
if err != nil {
if err == sql.ErrNoRows {
http.Error(w, "Enquiry not found", http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(enquiry)
}
func (h *EnquiryHandler) Create(w http.ResponseWriter, r *http.Request) {
var req CreateEnquiryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
now := time.Now()
result, err := h.queries.CreateEnquiry(r.Context(), db.CreateEnquiryParams{
Created: now,
Title: req.Title,
UserID: req.UserID,
CustomerID: req.CustomerID,
ContactID: req.ContactID,
ContactUserID: req.ContactUserID,
StateID: req.StateID,
CountryID: req.CountryID,
PrincipleID: req.PrincipleID,
StatusID: req.StatusID,
Comments: req.Comments,
PrincipleCode: req.PrincipleCode,
Gst: req.Gst,
BillingAddressID: req.BillingAddressID,
ShippingAddressID: req.ShippingAddressID,
Posted: req.Posted,
Archived: int8(0),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
id, err := result.LastInsertId()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Return the created enquiry
enquiry, err := h.queries.GetEnquiry(r.Context(), int32(id))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(enquiry)
}
func (h *EnquiryHandler) Update(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
var req UpdateEnquiryRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
err = h.queries.UpdateEnquiry(r.Context(), db.UpdateEnquiryParams{
Title: req.Title,
UserID: req.UserID,
CustomerID: req.CustomerID,
ContactID: req.ContactID,
ContactUserID: req.ContactUserID,
StateID: req.StateID,
CountryID: req.CountryID,
PrincipleID: req.PrincipleID,
StatusID: req.StatusID,
Comments: req.Comments,
PrincipleCode: req.PrincipleCode,
Gst: req.Gst,
BillingAddressID: req.BillingAddressID,
ShippingAddressID: req.ShippingAddressID,
Posted: req.Posted,
Submitted: req.Submitted,
ID: int32(id),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Return the updated enquiry
enquiry, err := h.queries.GetEnquiry(r.Context(), int32(id))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(enquiry)
}
func (h *EnquiryHandler) Delete(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
err = h.queries.ArchiveEnquiry(r.Context(), int32(id))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h *EnquiryHandler) Undelete(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
err = h.queries.UnarchiveEnquiry(r.Context(), int32(id))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h *EnquiryHandler) UpdateStatus(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
var req struct {
StatusID int32 `json:"status_id"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
err = h.queries.UpdateEnquiryStatus(r.Context(), db.UpdateEnquiryStatusParams{
StatusID: req.StatusID,
ID: int32(id),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Return the updated enquiry
enquiry, err := h.queries.GetEnquiry(r.Context(), int32(id))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(enquiry)
}
func (h *EnquiryHandler) MarkSubmitted(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid enquiry ID", http.StatusBadRequest)
return
}
today := time.Now()
err = h.queries.MarkEnquirySubmitted(r.Context(), db.MarkEnquirySubmittedParams{
Submitted: sql.NullTime{Time: today, Valid: true},
ID: int32(id),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
func (h *EnquiryHandler) Search(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
if query == "" {
h.List(w, r)
return
}
page := 1
if p := r.URL.Query().Get("page"); p != "" {
if val, err := strconv.Atoi(p); err == nil && val > 0 {
page = val
}
}
limit := 150
offset := (page - 1) * limit
enquiries, err := h.queries.SearchEnquiries(r.Context(), db.SearchEnquiriesParams{
CONCAT: query,
CONCAT_2: query,
CONCAT_3: query,
Limit: int32(limit),
Offset: int32(offset),
})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(enquiries)
}