Customer Completed

This commit is contained in:
Juanda Ritonga
2024-12-23 11:20:33 +07:00
parent 876b46b10c
commit 8be33d521f
6 changed files with 242 additions and 18 deletions
+162
View File
@@ -1,13 +1,16 @@
package user
import (
"fmt"
"furtuna-be/internal/constants/role"
"net/http"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/xuri/excelize/v2"
"furtuna-be/internal/common/errors"
"furtuna-be/internal/entity"
@@ -24,11 +27,14 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/user")
route.POST("/", jwt, h.Create)
route.POST("/customer", jwt, h.CreateCustomer)
route.POST("/customer-bulk-excel", jwt, h.CreateCustomersFromExcel)
route.GET("/list", jwt, h.GetAll)
route.GET("/customer/list", jwt, h.GetAllCustomer)
route.GET("/:id", jwt, h.GetByID)
route.PUT("/:id", jwt, h.Update)
route.PUT("/customer/:id", jwt, h.UpdateCustomer)
route.DELETE("/customer/:id", jwt, h.DeleteCustomer)
route.DELETE("/:id", jwt, h.Delete)
}
@@ -94,6 +100,128 @@ func (h *Handler) Create(c *gin.Context) {
})
}
func (h *Handler) CreateCustomer(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.User
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.Create(ctx, req.ToEntity(ctx, "CUSTOMER"))
if err != nil {
response.ErrorWrapper(c, err)
return
}
resp := response.User{
ID: res.ID,
Name: res.Name,
Email: res.Email,
RoleID: int64(res.RoleID),
PartnerID: res.PartnerID,
Status: string(res.Status),
PhoneNumber: res.PhoneNumber,
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: resp,
})
}
func (h *Handler) CreateCustomersFromExcel(c *gin.Context) {
ctx := request.GetMyContext(c)
// var req request.User
var responseData []response.User
file, err := c.FormFile("file")
if err != nil {
fmt.Println("err", err.Error())
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
f, err := file.Open()
if err != nil {
fmt.Println("err", err.Error())
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
defer f.Close()
excel, err := excelize.OpenReader(f)
if err != nil {
fmt.Println("err", err.Error())
response.ErrorWrapper(c, errors.ErrorBadRequest)
// c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "Failed to read Excel file"})
return
}
// sheetName := excel.GetSheetName(1) // Assuming the data is in the first sheet
rows, err := excel.GetRows("Sheet1")
if err != nil {
fmt.Println("err", err.Error())
response.ErrorWrapper(c, errors.ErrorBadRequest)
// c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "Failed to read rows from Excel"})
return
}
var phoneNumbers []string
for _, row := range rows {
if len(row) > 0 {
phoneNumber := strings.TrimSpace(row[0])
if phoneNumber != "" {
phoneNumbers = append(phoneNumbers, phoneNumber)
}
}
}
// c.JSON(http.StatusOK, response.BaseResponse{
// Success: true,
// Status: http.StatusOK,
// Data: phoneNumbers,
// })
// return
if len(phoneNumbers) == 0 {
response.ErrorWrapper(c, errors.ErrorBadRequest)
// c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "No phone numbers found in the Excel file"})
return
}
// var createdCustomers []CustomerResponse
for _, phone := range phoneNumbers {
req := request.User{
PhoneNumber: phone,
Email: "",
}
res, err := h.service.Create(ctx, req.ToEntity(ctx, "CUSTOMER"))
// res, err := h.service.Create(c, customer)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"message": fmt.Sprintf("Failed to create customer for phone number %s: %v", phone, err),
})
return
}
responseData = append(responseData, response.User{PhoneNumber: res.PhoneNumber})
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: responseData,
})
}
// Update handles the update of an existing user.
// @Summary Update an existing user
// @Description Update the details of an existing user based on the provided ID.
@@ -309,6 +437,40 @@ func (h *Handler) Delete(c *gin.Context) {
})
}
func (h *Handler) DeleteCustomer(c *gin.Context) {
ctx := request.GetMyContext(c)
id := c.Param("id")
// Parse the ID into an int64 (or whatever type is used for customer ID)
customerID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
// Handle invalid ID format error
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
// Call the service to delete the customer
err = h.service.Delete(ctx, customerID)
if err != nil {
// If there was an error deleting, return a 500 Internal Server Error
c.JSON(http.StatusInternalServerError, response.BaseResponse{
Success: false,
Status: http.StatusInternalServerError,
Message: err.Error(),
Data: nil,
})
return
}
// Return a success response after deletion
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Message: "Customer deleted successfully", // Added success message
Data: nil,
})
}
func (h *Handler) toUserResponse(resp *entity.User) response.User {
return response.User{
ID: resp.ID,
+40 -1
View File
@@ -4,8 +4,11 @@ import (
"furtuna-be/internal/common/mycontext"
"furtuna-be/internal/constants/role"
"furtuna-be/internal/entity"
"github.com/go-playground/validator/v10"
"math/rand"
"strings"
"time"
"github.com/go-playground/validator/v10"
)
type User struct {
@@ -29,11 +32,29 @@ func (e *User) Validate() error {
return nil
}
func RandomEmail() string {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
const length = 8
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
randomString := make([]byte, length)
for i := range randomString {
randomString[i] = charset[seededRand.Intn(len(charset))]
}
return string(randomString) + "@example.com"
}
func (u *User) ToEntity(ctx mycontext.Context, userType string) *entity.User {
if !ctx.IsAdmin() {
u.PartnerID = ctx.GetPartnerID()
}
if u.Email == "" {
u.Email = RandomEmail()
}
return &entity.User{
Name: u.Name,
Email: strings.ToLower(u.Email),
@@ -47,6 +68,24 @@ func (u *User) ToEntity(ctx mycontext.Context, userType string) *entity.User {
}
}
type Customer struct {
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
PhoneNumber string `json:"phone_number" binding:"required"`
RoleID int64 `json:"role_id" binding:"required"`
SiteID *int64 `json:"site_id" binding:"required"`
}
func (c *Customer) ToEntity(ctx mycontext.Context, userType string) entity.Customer {
return entity.Customer{
Name: c.Name,
Email: c.Email,
PhoneNumber: c.PhoneNumber,
SiteID: c.SiteID,
PartnerID: ctx.GetPartnerID(),
}
}
type UserParam struct {
Search string `form:"search" json:"search" example:"admin,branch1"`
Name string `form:"name" json:"name" example:"Admin 1"`
+1
View File
@@ -124,6 +124,7 @@ func (b *UserRepository) GetAllUsers(ctx context.Context, req entity.UserSearch)
return users, int(total), nil
}
func (b *UserRepository) GetAllCustomer(ctx context.Context, req entity.CustomerSearch) (entity.CustomerList, int, error) {
var users []*entity.UserDB
var total int64
+1
View File
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"furtuna-be/internal/common/mycontext"
"gorm.io/gorm"
"go.uber.org/zap"