2026-02-06 17:35:29 +01:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net/http"
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"erp_system/internal/models"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerList(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
search := r.URL.Query().Get("search")
|
2026-02-07 07:47:20 +01:00
|
|
|
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
|
|
|
|
if page < 1 {
|
|
|
|
|
page = 1
|
|
|
|
|
}
|
|
|
|
|
limit := 10
|
|
|
|
|
|
|
|
|
|
customers, total, err := models.CustomerGetPaginated(h.DB, search, page, limit)
|
2026-02-06 17:35:29 +01:00
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-07 07:47:20 +01:00
|
|
|
totalPages := (total + limit - 1) / limit
|
|
|
|
|
|
2026-02-06 17:35:29 +01:00
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": "Customers",
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customers": customers,
|
|
|
|
|
"Search": search,
|
2026-02-07 07:47:20 +01:00
|
|
|
"Page": page,
|
|
|
|
|
"TotalPages": totalPages,
|
|
|
|
|
"HasPrev": page > 1,
|
|
|
|
|
"HasNext": page < totalPages,
|
|
|
|
|
"PrevPage": page - 1,
|
|
|
|
|
"NextPage": page + 1,
|
2026-02-06 17:35:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HTMX partial for search
|
|
|
|
|
if r.Header.Get("HX-Request") == "true" && r.URL.Query().Get("partial") == "true" {
|
|
|
|
|
h.renderPartial(w, "customers/list.html", "customer-table", data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/list.html"}, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerNew(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": "New Customer",
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customer": &models.Customer{},
|
|
|
|
|
"IsNew": true,
|
|
|
|
|
}
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/form.html"}, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerCreate(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
c := &models.Customer{
|
|
|
|
|
Name: r.FormValue("name"),
|
|
|
|
|
Email: r.FormValue("email"),
|
|
|
|
|
Phone: r.FormValue("phone"),
|
|
|
|
|
Address: r.FormValue("address"),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.Name == "" {
|
|
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": "New Customer",
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customer": c,
|
|
|
|
|
"IsNew": true,
|
|
|
|
|
"Error": "Name is required",
|
|
|
|
|
}
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/form.html"}, data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := models.CustomerInsert(h.DB, c); err != nil {
|
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Header.Get("HX-Request") == "true" {
|
|
|
|
|
w.Header().Set("HX-Redirect", "/customers/"+strconv.Itoa(c.ID))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
http.Redirect(w, r, "/customers/"+strconv.Itoa(c.ID), http.StatusSeeOther)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerDetail(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
id, _ := strconv.Atoi(r.PathValue("id"))
|
|
|
|
|
customer, err := models.CustomerGetByID(h.DB, id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, "Customer not found", http.StatusNotFound)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get customer's orders
|
|
|
|
|
orders, _ := models.OrderGetAll(h.DB, "")
|
|
|
|
|
var customerOrders []models.Order
|
|
|
|
|
for _, o := range orders {
|
|
|
|
|
if o.CustomerID == id {
|
|
|
|
|
customerOrders = append(customerOrders, o)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get customer's invoices
|
|
|
|
|
invoices, _ := models.InvoiceGetByCustomerID(h.DB, id)
|
|
|
|
|
|
|
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": customer.Name,
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customer": customer,
|
|
|
|
|
"Orders": customerOrders,
|
|
|
|
|
"Invoices": invoices,
|
|
|
|
|
}
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/detail.html"}, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerEdit(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
id, _ := strconv.Atoi(r.PathValue("id"))
|
|
|
|
|
customer, err := models.CustomerGetByID(h.DB, id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, "Customer not found", http.StatusNotFound)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": "Edit " + customer.Name,
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customer": customer,
|
|
|
|
|
"IsNew": false,
|
|
|
|
|
}
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/form.html"}, data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerUpdate(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
id, _ := strconv.Atoi(r.PathValue("id"))
|
|
|
|
|
c := &models.Customer{
|
|
|
|
|
ID: id,
|
|
|
|
|
Name: r.FormValue("name"),
|
|
|
|
|
Email: r.FormValue("email"),
|
|
|
|
|
Phone: r.FormValue("phone"),
|
|
|
|
|
Address: r.FormValue("address"),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.Name == "" {
|
|
|
|
|
data := map[string]interface{}{
|
|
|
|
|
"Title": "Edit Customer",
|
|
|
|
|
"Username": h.getUsername(r),
|
|
|
|
|
"ActivePage": "customers",
|
|
|
|
|
"Customer": c,
|
|
|
|
|
"IsNew": false,
|
|
|
|
|
"Error": "Name is required",
|
|
|
|
|
}
|
|
|
|
|
h.render(w, []string{"layout.html", "customers/form.html"}, data)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := models.CustomerUpdate(h.DB, c); err != nil {
|
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Header.Get("HX-Request") == "true" {
|
|
|
|
|
w.Header().Set("HX-Redirect", "/customers/"+strconv.Itoa(id))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
http.Redirect(w, r, "/customers/"+strconv.Itoa(id), http.StatusSeeOther)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handler) CustomerDelete(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
id, _ := strconv.Atoi(r.PathValue("id"))
|
|
|
|
|
if err := models.CustomerDelete(h.DB, id); err != nil {
|
|
|
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.Header.Get("HX-Request") == "true" {
|
|
|
|
|
w.Header().Set("HX-Redirect", "/customers")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
http.Redirect(w, r, "/customers", http.StatusSeeOther)
|
|
|
|
|
}
|