package handlers import ( "net/http" "strconv" "sale/internal/models" "sale/internal/schemas" "sale/internal/utils" "github.com/gin-gonic/gin" ) type SystemHandler struct{} func NewSystemHandler() *SystemHandler { return &SystemHandler{} } func (h *SystemHandler) GetSettings(c *gin.Context) { var settings []models.SystemSetting utils.DB.Find(&settings) result := make(map[string]string) for _, s := range settings { result[s.Key] = s.Value } c.JSON(http.StatusOK, gin.H{"data": result}) } func (h *SystemHandler) GetPublicSettings(c *gin.Context) { publicKeys := []string{ "payment_channel_fee_rate", "shipping_fee_first_weight", "shipping_fee_per_gram", "service_fee_rate", "tax_rate", "enabled_payments", } var settings []models.SystemSetting utils.DB.Where("`key` IN ?", publicKeys).Find(&settings) result := make(map[string]string) for _, s := range settings { result[s.Key] = s.Value } c.JSON(http.StatusOK, gin.H{"data": result}) } func (h *SystemHandler) GetStats(c *gin.Context) { var userCount, productCount, orderCount int64 var totalRevenue float64 utils.DB.Model(&models.User{}).Count(&userCount) utils.DB.Model(&models.Product{}).Count(&productCount) utils.DB.Model(&models.Order{}).Count(&orderCount) utils.DB.Model(&models.Order{}).Where("status = ?", "completed").Select("COALESCE(SUM(total_amount), 0)").Scan(&totalRevenue) c.JSON(http.StatusOK, gin.H{ "data": gin.H{ "users": userCount, "products": productCount, "orders": orderCount, "revenue": totalRevenue, }, }) } func (h *SystemHandler) UpdateSettings(c *gin.Context) { var req schemas.UpdateSettingsRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } for key, value := range req.Settings { var setting models.SystemSetting result := utils.DB.Where("`key` = ?", key).First(&setting) if result.Error != nil { utils.DB.Create(&models.SystemSetting{Key: key, Value: value}) } else { utils.DB.Model(&setting).Update("value", value) } } c.JSON(http.StatusOK, gin.H{"message": "Settings updated successfully"}) } func (h *SystemHandler) UpdateSMTP(c *gin.Context) { var req map[string]string if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } smtpKeys := []string{"smtp_host", "smtp_port", "smtp_user", "smtp_password", "smtp_from"} for _, key := range smtpKeys { if value, ok := req[key]; ok { var setting models.SystemSetting result := utils.DB.Where("`key` = ?", key).First(&setting) if result.Error != nil { utils.DB.Create(&models.SystemSetting{Key: key, Value: value}) } else { utils.DB.Model(&setting).Update("value", value) } } } c.JSON(http.StatusOK, gin.H{"message": "SMTP settings updated successfully"}) } func (h *SystemHandler) UpdatePayment(c *gin.Context) { var req map[string]string if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } for key, value := range req { var setting models.SystemSetting result := utils.DB.Where("`key` = ?", key).First(&setting) if result.Error != nil { utils.DB.Create(&models.SystemSetting{Key: key, Value: value}) } else { utils.DB.Model(&setting).Update("value", value) } } c.JSON(http.StatusOK, gin.H{"message": "Payment settings updated successfully"}) } type SupplierHandler struct{} func NewSupplierHandler() *SupplierHandler { return &SupplierHandler{} } func (h *SupplierHandler) List(c *gin.Context) { var suppliers []models.User utils.DB.Where("role = ?", "supplier").Find(&suppliers) c.JSON(http.StatusOK, gin.H{"data": suppliers}) } func (h *SupplierHandler) Create(c *gin.Context) { var req schemas.AddSupplierRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } hashedPassword, _ := utils.HashPassword(req.Password) supplier := models.User{ Username: req.Username, Email: req.Email, PasswordHash: hashedPassword, Role: "supplier", InviteCode: utils.GenerateInviteCode(), IsActive: true, } utils.DB.Create(&supplier) c.JSON(http.StatusCreated, gin.H{"data": supplier}) } func (h *SupplierHandler) Update(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var supplier models.User if err := utils.DB.Where("id = ? AND role = ?", id, "supplier").First(&supplier).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Supplier not found"}) return } var req struct { Username *string `json:"username"` Email *string `json:"email"` IsActive *bool `json:"is_active"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } updates := make(map[string]interface{}) if req.Username != nil { updates["username"] = *req.Username } if req.Email != nil { updates["email"] = *req.Email } if req.IsActive != nil { updates["is_active"] = *req.IsActive } utils.DB.Model(&supplier).Updates(updates) utils.DB.Where("id = ?", id).First(&supplier) c.JSON(http.StatusOK, gin.H{"data": supplier}) } func (h *SupplierHandler) Delete(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) utils.DB.Where("id = ? AND role = ?", id, "supplier").Delete(&models.User{}) c.JSON(http.StatusOK, gin.H{"message": "Supplier deleted successfully"}) } func (h *SupplierHandler) Authorize(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var req schemas.AuthorizeSupplierRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } auth := models.SupplierAuthorization{ SupplierID: uint(id), Type: req.Type, RefID: req.RefID, } utils.DB.Create(&auth) c.JSON(http.StatusCreated, gin.H{"data": auth}) } type InventoryHandler struct{} func NewInventoryHandler() *InventoryHandler { return &InventoryHandler{} } func (h *InventoryHandler) SupplierList(c *gin.Context) { userID := c.GetUint("user_id") var inventory []models.Inventory utils.DB.Where("supplier_id = ?", userID).Preload("Product").Find(&inventory) c.JSON(http.StatusOK, gin.H{"data": inventory}) } func (h *InventoryHandler) Update(c *gin.Context) { userID := c.GetUint("user_id") id, _ := strconv.Atoi(c.Param("id")) var inventory models.Inventory if err := utils.DB.Where("id = ? AND supplier_id = ?", id, userID).First(&inventory).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Inventory not found"}) return } var req schemas.UpdateInventoryRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } utils.DB.Model(&inventory).Update("quantity", req.Quantity) c.JSON(http.StatusOK, gin.H{"data": inventory}) } func (h *InventoryHandler) AdminList(c *gin.Context) { var inventory []models.Inventory utils.DB.Preload("Product").Find(&inventory) c.JSON(http.StatusOK, gin.H{"data": inventory}) }