400 lines
12 KiB
Go
400 lines
12 KiB
Go
package handlers
|
|
|
|
import (
|
|
"aggios-app/backend/internal/api/middleware"
|
|
"aggios-app/backend/internal/domain"
|
|
"aggios-app/backend/internal/repository"
|
|
"encoding/json"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
type ERPHandler struct {
|
|
repo *repository.ERPRepository
|
|
}
|
|
|
|
func NewERPHandler(repo *repository.ERPRepository) *ERPHandler {
|
|
return &ERPHandler{repo: repo}
|
|
}
|
|
|
|
// ==================== FINANCE ====================
|
|
|
|
func (h *ERPHandler) CreateFinancialCategory(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
var cat domain.FinancialCategory
|
|
if err := json.NewDecoder(r.Body).Decode(&cat); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
cat.ID = uuid.New()
|
|
cat.TenantID, _ = uuid.Parse(tenantID)
|
|
cat.IsActive = true
|
|
|
|
if err := h.repo.CreateFinancialCategory(&cat); 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(cat)
|
|
}
|
|
|
|
func (h *ERPHandler) GetFinancialCategories(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
cats, err := h.repo.GetFinancialCategoriesByTenant(tenantID)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(cats)
|
|
}
|
|
|
|
func (h *ERPHandler) CreateBankAccount(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
var acc domain.BankAccount
|
|
if err := json.NewDecoder(r.Body).Decode(&acc); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
acc.ID = uuid.New()
|
|
acc.TenantID, _ = uuid.Parse(tenantID)
|
|
acc.IsActive = true
|
|
|
|
if err := h.repo.CreateBankAccount(&acc); 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(acc)
|
|
}
|
|
|
|
func (h *ERPHandler) GetBankAccounts(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
accs, err := h.repo.GetBankAccountsByTenant(tenantID)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(accs)
|
|
}
|
|
|
|
func (h *ERPHandler) CreateTransaction(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
|
var t domain.FinancialTransaction
|
|
if err := json.NewDecoder(r.Body).Decode(&t); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
t.ID = uuid.New()
|
|
t.TenantID, _ = uuid.Parse(tenantID)
|
|
t.CreatedBy, _ = uuid.Parse(userID)
|
|
|
|
if err := h.repo.CreateTransaction(&t); 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(t)
|
|
}
|
|
|
|
func (h *ERPHandler) GetTransactions(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
txs, err := h.repo.GetTransactionsByTenant(tenantID)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(txs)
|
|
}
|
|
|
|
// ==================== PRODUCTS ====================
|
|
|
|
func (h *ERPHandler) CreateProduct(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
var p domain.Product
|
|
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
p.ID = uuid.New()
|
|
p.TenantID, _ = uuid.Parse(tenantID)
|
|
p.IsActive = true
|
|
|
|
if err := h.repo.CreateProduct(&p); 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(p)
|
|
}
|
|
|
|
func (h *ERPHandler) GetProducts(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
products, err := h.repo.GetProductsByTenant(tenantID)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(products)
|
|
}
|
|
|
|
// ==================== ORDERS ====================
|
|
|
|
type createOrderRequest struct {
|
|
Order domain.Order `json:"order"`
|
|
Items []domain.OrderItem `json:"items"`
|
|
}
|
|
|
|
func (h *ERPHandler) CreateOrder(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
userID, _ := r.Context().Value(middleware.UserIDKey).(string)
|
|
var req createOrderRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
req.Order.ID = uuid.New()
|
|
req.Order.TenantID, _ = uuid.Parse(tenantID)
|
|
req.Order.CreatedBy, _ = uuid.Parse(userID)
|
|
if req.Order.Status == "" {
|
|
req.Order.Status = "draft"
|
|
}
|
|
|
|
for i := range req.Items {
|
|
req.Items[i].ID = uuid.New()
|
|
req.Items[i].OrderID = req.Order.ID
|
|
req.Items[i].CreatedAt = time.Now()
|
|
}
|
|
|
|
if err := h.repo.CreateOrder(&req.Order, req.Items); 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(req.Order)
|
|
}
|
|
|
|
func (h *ERPHandler) GetOrders(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
orders, err := h.repo.GetOrdersByTenant(tenantID)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(orders)
|
|
}
|
|
|
|
// ==================== ENTITIES ====================
|
|
|
|
func (h *ERPHandler) CreateEntity(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
var e domain.Entity
|
|
if err := json.NewDecoder(r.Body).Decode(&e); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
e.ID = uuid.New()
|
|
e.TenantID, _ = uuid.Parse(tenantID)
|
|
if e.Status == "" {
|
|
e.Status = "active"
|
|
}
|
|
|
|
if err := h.repo.CreateEntity(&e); 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(e)
|
|
}
|
|
|
|
func (h *ERPHandler) GetEntities(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
entityType := r.URL.Query().Get("type") // customer or supplier
|
|
|
|
entities, err := h.repo.GetEntitiesByTenant(tenantID, entityType)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(entities)
|
|
}
|
|
func (h *ERPHandler) UpdateTransaction(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
http.Error(w, "invalid id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var t domain.FinancialTransaction
|
|
if err := json.NewDecoder(r.Body).Decode(&t); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
t.ID = id
|
|
t.TenantID, _ = uuid.Parse(tenantID)
|
|
|
|
if err := h.repo.UpdateTransaction(&t); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) DeleteTransaction(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
if err := h.repo.DeleteTransaction(idStr, tenantID); err != nil {
|
|
log.Printf("❌ Error deleting transaction: %v", err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) UpdateEntity(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
http.Error(w, "invalid id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var e domain.Entity
|
|
if err := json.NewDecoder(r.Body).Decode(&e); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
e.ID = id
|
|
e.TenantID, _ = uuid.Parse(tenantID)
|
|
|
|
if err := h.repo.UpdateEntity(&e); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) DeleteEntity(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
if err := h.repo.DeleteEntity(idStr, tenantID); err != nil {
|
|
log.Printf("❌ Error deleting entity: %v", err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) UpdateProduct(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
http.Error(w, "invalid id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var p domain.Product
|
|
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
p.ID = id
|
|
p.TenantID, _ = uuid.Parse(tenantID)
|
|
|
|
if err := h.repo.UpdateProduct(&p); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) DeleteProduct(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
if err := h.repo.DeleteProduct(idStr, tenantID); err != nil {
|
|
log.Printf("❌ Error deleting product: %v", err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) UpdateBankAccount(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
id, err := uuid.Parse(idStr)
|
|
if err != nil {
|
|
http.Error(w, "invalid id", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var a domain.BankAccount
|
|
if err := json.NewDecoder(r.Body).Decode(&a); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
a.ID = id
|
|
a.TenantID, _ = uuid.Parse(tenantID)
|
|
|
|
if err := h.repo.UpdateBankAccount(&a); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) DeleteBankAccount(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
if err := h.repo.DeleteBankAccount(idStr, tenantID); err != nil {
|
|
log.Printf("❌ Error deleting bank account: %v", err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func (h *ERPHandler) DeleteOrder(w http.ResponseWriter, r *http.Request) {
|
|
tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string)
|
|
idStr := mux.Vars(r)["id"]
|
|
if err := h.repo.DeleteOrder(idStr, tenantID); err != nil {
|
|
log.Printf("❌ Error deleting order: %v", err)
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|