471 lines
12 KiB
Go
471 lines
12 KiB
Go
package handlers
|
|
|
|
import (
|
|
"aggios-app/backend/internal/domain"
|
|
"aggios-app/backend/internal/repository"
|
|
"aggios-app/backend/internal/api/middleware"
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
type CRMHandler struct {
|
|
repo *repository.CRMRepository
|
|
}
|
|
|
|
func NewCRMHandler(repo *repository.CRMRepository) *CRMHandler {
|
|
return &CRMHandler{repo: repo}
|
|
}
|
|
|
|
// ==================== CUSTOMERS ====================
|
|
|
|
func (h *CRMHandler) CreateCustomer(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
var customer domain.CRMCustomer
|
|
if err := json.NewDecoder(r.Body).Decode(&customer); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Invalid request body",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
customer.ID = uuid.New().String()
|
|
customer.TenantID = tenantID
|
|
customer.CreatedBy = userID
|
|
customer.IsActive = true
|
|
|
|
if err := h.repo.CreateCustomer(&customer); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to create customer",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"customer": customer,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) GetCustomers(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
customers, err := h.repo.GetCustomersByTenant(tenantID)
|
|
if err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to fetch customers",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
if customers == nil {
|
|
customers = []domain.CRMCustomer{}
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"customers": customers,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) GetCustomer(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
customerID := vars["id"]
|
|
|
|
customer, err := h.repo.GetCustomerByID(customerID, tenantID)
|
|
if err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusNotFound)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Customer not found",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
// Buscar listas do cliente
|
|
lists, _ := h.repo.GetCustomerLists(customerID)
|
|
if lists == nil {
|
|
lists = []domain.CRMList{}
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"customer": customer,
|
|
"lists": lists,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) UpdateCustomer(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
customerID := vars["id"]
|
|
|
|
var customer domain.CRMCustomer
|
|
if err := json.NewDecoder(r.Body).Decode(&customer); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Invalid request body",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
customer.ID = customerID
|
|
customer.TenantID = tenantID
|
|
|
|
if err := h.repo.UpdateCustomer(&customer); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to update customer",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "Customer updated successfully",
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) DeleteCustomer(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
customerID := vars["id"]
|
|
|
|
if err := h.repo.DeleteCustomer(customerID, tenantID); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to delete customer",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "Customer deleted successfully",
|
|
})
|
|
}
|
|
|
|
// ==================== LISTS ====================
|
|
|
|
func (h *CRMHandler) CreateList(w http.ResponseWriter, r *http.Request) {
|
|
tenantIDVal := r.Context().Value(middleware.TenantIDKey)
|
|
userIDVal := r.Context().Value(middleware.UserIDKey)
|
|
|
|
log.Printf("🔍 CreateList DEBUG: tenantID type=%T value=%v | userID type=%T value=%v",
|
|
tenantIDVal, tenantIDVal, userIDVal, userIDVal)
|
|
|
|
tenantID, ok := tenantIDVal.(string)
|
|
if !ok || tenantID == "" {
|
|
log.Printf("❌ CreateList: Missing or invalid tenant_id")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
userID, _ := userIDVal.(string)
|
|
|
|
var list domain.CRMList
|
|
if err := json.NewDecoder(r.Body).Decode(&list); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Invalid request body",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
list.ID = uuid.New().String()
|
|
list.TenantID = tenantID
|
|
list.CreatedBy = userID
|
|
|
|
if list.Color == "" {
|
|
list.Color = "#3b82f6"
|
|
}
|
|
|
|
if err := h.repo.CreateList(&list); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to create list",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"list": list,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) GetLists(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
lists, err := h.repo.GetListsByTenant(tenantID)
|
|
if err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to fetch lists",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
if lists == nil {
|
|
lists = []domain.CRMListWithCustomers{}
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"lists": lists,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) GetList(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
listID := vars["id"]
|
|
|
|
list, err := h.repo.GetListByID(listID, tenantID)
|
|
if err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusNotFound)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "List not found",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
// Buscar clientes da lista
|
|
customers, _ := h.repo.GetListCustomers(listID, tenantID)
|
|
if customers == nil {
|
|
customers = []domain.CRMCustomer{}
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"list": list,
|
|
"customers": customers,
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) UpdateList(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
listID := vars["id"]
|
|
|
|
var list domain.CRMList
|
|
if err := json.NewDecoder(r.Body).Decode(&list); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Invalid request body",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
list.ID = listID
|
|
list.TenantID = tenantID
|
|
|
|
if err := h.repo.UpdateList(&list); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to update list",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "List updated successfully",
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) DeleteList(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
|
|
if tenantID == "" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Missing tenant_id",
|
|
})
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
listID := vars["id"]
|
|
|
|
if err := h.repo.DeleteList(listID, tenantID); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to delete list",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "List deleted successfully",
|
|
})
|
|
}
|
|
|
|
// ==================== CUSTOMER <-> LIST ====================
|
|
|
|
func (h *CRMHandler) AddCustomerToList(w http.ResponseWriter, r *http.Request) {
|
|
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
|
|
|
vars := mux.Vars(r)
|
|
customerID := vars["customer_id"]
|
|
listID := vars["list_id"]
|
|
|
|
if err := h.repo.AddCustomerToList(customerID, listID, userID); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to add customer to list",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "Customer added to list successfully",
|
|
})
|
|
}
|
|
|
|
func (h *CRMHandler) RemoveCustomerFromList(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
customerID := vars["customer_id"]
|
|
listID := vars["list_id"]
|
|
|
|
if err := h.repo.RemoveCustomerFromList(customerID, listID); err != nil {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"error": "Failed to remove customer from list",
|
|
"message": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"message": "Customer removed from list successfully",
|
|
})
|
|
}
|
|
|