fix(erp): enable erp pages and menu items
This commit is contained in:
399
backend/internal/api/handlers/erp_handler.go
Normal file
399
backend/internal/api/handlers/erp_handler.go
Normal file
@@ -0,0 +1,399 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user