This commit is contained in:
aditya.siregar
2025-04-05 11:28:06 +08:00
parent 118ec58521
commit c642c5c61b
35 changed files with 1194 additions and 212 deletions
+32 -12
View File
@@ -1,6 +1,8 @@
package customerauth
import (
auth2 "enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/services/v2/customer"
"fmt"
"net/http"
"strings"
@@ -8,7 +10,6 @@ import (
"github.com/gin-gonic/gin"
"enaklo-pos-be/internal/common/errors"
auth2 "enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services"
)
@@ -16,6 +17,7 @@ import (
type AuthHandler struct {
service services.Auth
userService services.User
customerSvc customer.Service
}
func (a *AuthHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
@@ -24,12 +26,14 @@ func (a *AuthHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
authRoute.POST("/forgot-password", a.ForgotPassword)
authRoute.POST("/reset-password", jwt, a.ResetPassword)
authRoute.POST("/register", a.Register)
authRoute.POST("/verify", a.VerifyRegistration)
}
func NewAuthHandler(service services.Auth, userService services.User) *AuthHandler {
func NewAuthHandler(service services.Auth, userService services.User, customerSvc customer.Service) *AuthHandler {
return &AuthHandler{
service: service,
userService: userService,
customerSvc: customerSvc,
}
}
@@ -147,31 +151,47 @@ func (h *AuthHandler) ResetPassword(c *gin.Context) {
}
func (h *AuthHandler) Register(c *gin.Context) {
var req auth2.UserRegister
var req auth2.CustomerRegister
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := auth2.GetMyContext(c)
res, err := h.userService.Create(ctx, req.ToEntity())
customer, err := h.customerSvc.RegistrationMember(ctx, req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
resp := response.UserRegister{
ID: res.ID,
Name: res.Name,
Email: res.Email,
Status: string(res.Status),
CreatedAt: res.CreatedAt,
UpdatedAt: res.UpdatedAt,
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.CustomerRegistrationResp{
EmailVerificationRequired: true,
PhoneVerificationRequired: false,
VerificationID: customer.VerificationID,
},
})
}
func (h *AuthHandler) VerifyRegistration(c *gin.Context) {
var req auth2.VerifyEmailRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := auth2.GetMyContext(c)
err := h.customerSvc.VerifyOTP(ctx, req.VerificationID, req.OTPCode)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: resp,
Message: "Email verification successful",
})
}
+173
View File
@@ -0,0 +1,173 @@
package http
import (
"enaklo-pos-be/internal/common/errors"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services/v2/inprogress_order"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"net/http"
"strconv"
)
type InProgressOrderHandler struct {
service inprogress_order.InProgressOrderService
}
func NewInProgressOrderHandler(service inprogress_order.InProgressOrderService) *InProgressOrderHandler {
return &InProgressOrderHandler{
service: service,
}
}
func (h *InProgressOrderHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/inprogress-order")
route.POST("/save", jwt, h.Save)
route.GET("/list", jwt, h.GetByPartnerID)
}
type CreateInProgressOrderRequest struct {
CustomerID *int64 `json:"customer_id"`
CustomerName string `json:"customer_name" validate:"required_without=CustomerID"`
CustomerEmail string `json:"customer_email"`
CustomerPhoneNumber string `json:"customer_phone_number"`
PaymentMethod string `json:"payment_method"`
OrderItems []InProgressOrderItemRequest `json:"order_items" validate:"required,min=1,dive"`
OrderType string `json:"order_type"`
PaymentProvider string `json:"payment_provider"`
TableNumber string `json:"table_number"`
InProgressOrderID string `json:"in_progress_order_id"`
}
type InProgressOrderItemRequest struct {
ProductID int64 `json:"product_id" validate:"required"`
Quantity int `json:"quantity" validate:"required,min=1"`
}
type UpdateInProgressOrderRequest struct {
Status string `json:"status" validate:"required"`
Amount float64 `json:"amount" validate:"required,min=0"`
Fee float64 `json:"fee" validate:"min=0"`
Total float64 `json:"total" validate:"required,min=0"`
PaymentType string `json:"payment_type" validate:"required"`
OrderItems []InProgressOrderItemRequest `json:"order_items" validate:"required,min=1,dive"`
}
func (h *InProgressOrderHandler) Save(c *gin.Context) {
ctx := request.GetMyContext(c)
userID := ctx.RequestedBy()
partnerID := ctx.GetPartnerID()
var req CreateInProgressOrderRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
validate := validator.New()
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
orderItems := make([]entity.InProgressOrderItem, len(req.OrderItems))
for i, item := range req.OrderItems {
orderItems[i] = entity.InProgressOrderItem{
ItemID: item.ProductID,
Quantity: item.Quantity,
}
}
order := &entity.InProgressOrder{
PartnerID: *partnerID,
CustomerID: req.CustomerID,
CustomerName: req.CustomerName,
CreatedBy: userID,
OrderItems: orderItems,
TableNumber: req.TableNumber,
OrderType: req.OrderType,
ID: req.InProgressOrderID,
}
_, err := h.service.Save(ctx, order)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusCreated, response.BaseResponse{
Success: true,
Status: http.StatusCreated,
})
}
func mapToInProgressOrderResponse(order *entity.InProgressOrder) map[string]interface{} {
orderItems := make([]map[string]interface{}, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = map[string]interface{}{
"id": item.ID,
"item_id": item.ItemID,
"quantity": item.Quantity,
"name": item.Product.Name,
"price": item.Product.Price,
"image": item.Product.Image,
}
}
return map[string]interface{}{
"id": order.ID,
"partner_id": order.PartnerID,
"customer_id": order.CustomerID,
"customer_name": order.CustomerName,
"payment_type": order.PaymentType,
"source": order.Source,
"created_by": order.CreatedBy,
"created_at": order.CreatedAt,
"updated_at": order.UpdatedAt,
"order_items": orderItems,
"table_number": order.TableNumber,
}
}
func (h *InProgressOrderHandler) GetByPartnerID(c *gin.Context) {
ctx := request.GetMyContext(c)
limitStr := c.DefaultQuery("limit", "10")
offsetStr := c.DefaultQuery("offset", "0")
limit, err := strconv.Atoi(limitStr)
if err != nil || limit < 0 {
limit = 10
}
offset, err := strconv.Atoi(offsetStr)
if err != nil || offset < 0 {
offset = 0
}
orders, err := h.service.GetOrdersByPartnerID(ctx, *ctx.GetPartnerID(), limit, offset)
if err != nil {
response.ErrorWrapper(c, err)
return
}
orderResponses := make([]map[string]interface{}, len(orders))
for i, order := range orders {
orderResponses[i] = mapToInProgressOrderResponse(order)
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: map[string]interface{}{
"orders": orderResponses,
"pagination": map[string]interface{}{
"limit": limit,
"offset": offset,
"count": len(orders),
},
},
})
}
+19 -3
View File
@@ -35,6 +35,17 @@ type InquiryRequest struct {
CustomerPhoneNumber string `json:"customer_phone_number"`
PaymentMethod string `json:"payment_method" validate:"required"`
OrderItems []OrderItemRequest `json:"order_items" validate:"required,min=1,dive"`
OrderType string `json:"order_type"`
PaymentProvider string `json:"payment_provider"`
TableNumber string `json:"table_number"`
}
func (o *InquiryRequest) GetPaymentProvider() string {
if o.PaymentMethod == "CASH" {
return "CASH"
}
return o.PaymentProvider
}
type OrderItemRequest struct {
@@ -43,8 +54,10 @@ type OrderItemRequest struct {
}
type ExecuteRequest struct {
PaymentMethod string `json:"payment_method" validate:"required"`
Token string `json:"token"`
PaymentMethod string `json:"payment_method" validate:"required"`
PaymentProvider string `json:"payment_provider"`
InProgressOrderID string `json:"in_progress_order_id"`
Token string `json:"token"`
}
func (h *Handler) Inquiry(c *gin.Context) {
@@ -82,6 +95,9 @@ func (h *Handler) Inquiry(c *gin.Context) {
CustomerName: req.CustomerName,
CustomerEmail: req.CustomerEmail,
CustomerPhoneNumber: req.CustomerPhoneNumber,
OrderType: req.OrderType,
PaymentProvider: req.GetPaymentProvider(),
TableNumber: req.TableNumber,
}
result, err := h.service.CreateOrderInquiry(ctx, orderReq)
@@ -112,7 +128,7 @@ func (h *Handler) Execute(c *gin.Context) {
return
}
result, err := h.service.ExecuteOrderInquiry(ctx, req.Token, req.PaymentMethod)
result, err := h.service.ExecuteOrderInquiry(ctx, req.Token, req.PaymentMethod, req.PaymentProvider, req.InProgressOrderID)
if err != nil {
response.ErrorWrapper(c, err)
return
+49
View File
@@ -0,0 +1,49 @@
package request
import (
"enaklo-pos-be/internal/entity"
"github.com/go-playground/validator/v10"
"strings"
"time"
)
type CustomerRegister struct {
Name string `json:"name" validate:"required" binding:"required"`
Email string `json:"email" validate:"required" binding:"required"`
PhoneNumber string `json:"phone_number" validate:"required" binding:"required"`
BirthDate string `json:"birth_date" validate:"required" binding:"required"`
Password string `json:"password" validate:"required" binding:"required"`
}
func (c *CustomerRegister) Validate() error {
validate := validator.New()
if err := validate.Struct(c); err != nil {
return err
}
return nil
}
func (c *CustomerRegister) GetBirthdate() (time.Time, error) {
parsedDate, err := time.Parse("02-01-2006", c.BirthDate)
if err != nil {
return time.Time{}, err
}
return parsedDate, nil
}
func (c *CustomerRegister) ToEntity() *entity.Customer {
birthdate, _ := c.GetBirthdate()
return &entity.Customer{
Name: c.Name,
Email: strings.ToLower(c.Email),
PhoneNumber: c.PhoneNumber,
Password: c.Password,
BirthDate: birthdate,
}
}
type VerifyEmailRequest struct {
VerificationID string `json:"verification_id" binding:"required"`
OTPCode string `json:"otp_code" binding:"required"`
}
+7 -5
View File
@@ -7,11 +7,13 @@ import (
)
type Order struct {
CustomerName string `json:"customer_name"`
CustomerPhone string `json:"customer_phone"`
CustomerEmail string `json:"customer_email"`
PaymentMethod string `json:"payment_method"`
OrderItems []OrderItem `json:"order_items"`
CustomerName string `json:"customer_name"`
CustomerPhone string `json:"customer_phone"`
CustomerEmail string `json:"customer_email"`
PaymentMethod string `json:"payment_method"`
PaymentProvider string `json:"payment_provider"`
TableNumber string `json:"table_number"`
OrderItems []OrderItem `json:"order_items"`
}
type CustomerOrder struct {
-2
View File
@@ -174,7 +174,5 @@ func (u *UserRegister) ToEntity() *entity.User {
Email: strings.ToLower(u.Email),
PhoneNumber: u.PhoneNumber,
Password: u.Password,
RoleID: role.Customer,
UserType: "CUSTOMER",
}
}
+6
View File
@@ -33,3 +33,9 @@ func MapToCustomerListResponse(customers *entity.MemberList) []CustomerResponse
return responseList
}
type CustomerRegistrationResp struct {
EmailVerificationRequired bool `json:"email_verification_required"`
PhoneVerificationRequired bool `json:"phone_verification_required"`
VerificationID string `json:"verification_id"`
}
+6 -6
View File
@@ -46,10 +46,10 @@ type CustomerList struct {
}
type UserRegister struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
PhoneNumber string `json:"phone_number"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
}