upodate system

This commit is contained in:
aditya.siregar
2025-06-27 13:01:39 +07:00
parent 1201b2e45b
commit f31f83e485
36 changed files with 2400 additions and 689 deletions
+48 -2
View File
@@ -5,9 +5,10 @@ import (
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services/v2/cashier_session"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
type CashierSessionHandler struct {
@@ -15,7 +16,9 @@ type CashierSessionHandler struct {
}
func NewCashierSession(service cashier_session.Service) *CashierSessionHandler {
return &CashierSessionHandler{service: service}
return &CashierSessionHandler{
service: service,
}
}
func (h *CashierSessionHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
@@ -26,6 +29,7 @@ func (h *CashierSessionHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFun
route.POST("/close/:id", h.CloseSession)
route.GET("/open", h.GetOpenSession)
route.GET("/report/:id", h.GetSessionReport)
route.GET("/history", h.GetSessionHistory)
}
func (h *CashierSessionHandler) OpenSession(c *gin.Context) {
@@ -121,3 +125,45 @@ func (h *CashierSessionHandler) GetSessionReport(c *gin.Context) {
Data: response.MapToCashierSessionReport(report),
})
}
func (h *CashierSessionHandler) GetSessionHistory(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
// Parse query parameters
limitStr := c.DefaultQuery("limit", "10")
offsetStr := c.DefaultQuery("offset", "0")
limit, err := strconv.Atoi(limitStr)
if err != nil || limit < 0 {
limit = 10
}
if limit > 50 {
limit = 50
}
offset, err := strconv.Atoi(offsetStr)
if err != nil || offset < 0 {
offset = 0
}
sessions, total, err := h.service.GetSessionHistory(ctx, *partnerID, limit, offset)
if err != nil {
response.ErrorWrapper(c, err)
return
}
responseData := make([]*response.CashierSessionResponse, len(sessions))
for i, session := range sessions {
responseData[i] = response.MapToCashierSessionResponse(session)
}
pagingMeta := response.NewPaginationHelper().BuildPagingMeta(offset, limit, total)
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: responseData,
PagingMeta: pagingMeta,
})
}
+1 -1
View File
@@ -27,7 +27,6 @@ func (h *CustomerOrderHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc
route.GET("/history", jwt, h.GetOrderHistory)
route.GET("/detail/:id", jwt, h.GetOrderID)
}
func (h *CustomerOrderHandler) GetOrderHistory(c *gin.Context) {
@@ -99,6 +98,7 @@ func (h *CustomerOrderHandler) GetOrderHistory(c *gin.Context) {
Price: item.Price,
Quantity: item.Quantity,
Subtotal: item.Price * float64(item.Quantity),
Status: item.Status,
})
}
+54 -119
View File
@@ -7,20 +7,23 @@ import (
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
"enaklo-pos-be/internal/services/v2/order"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
type Handler struct {
service order.Service
service order.Service
queryParser *request.QueryParser
}
func NewOrderHandler(service order.Service) *Handler {
return &Handler{
service: service,
service: service,
queryParser: request.NewQueryParser(),
}
}
@@ -39,6 +42,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route.GET("/revenue-overview", jwt, h.GetRevenueOverview)
route.GET("/sales-by-category", jwt, h.GetSalesByCategory)
route.GET("/popular-products", jwt, h.GetPopularProducts)
route.GET("/detail/:id", jwt, h.GetByID)
}
type InquiryRequest struct {
@@ -104,12 +108,10 @@ type VoidItemRequest struct {
}
type SplitBillRequest struct {
OrderID int64 `json:"order_id" validate:"required"`
Type string `json:"type" validate:"required,oneof=ITEM AMOUNT"`
PaymentMethod string `json:"payment_method" validate:"required"`
PaymentProvider string `json:"payment_provider"`
Items []SplitBillItemRequest `json:"items,omitempty" validate:"required_if=Type ITEM,dive"`
Amount float64 `json:"amount,omitempty" validate:"required_if=Type AMOUNT,min=0"`
OrderID int64 `json:"order_id" validate:"required"`
Type string `json:"type" validate:"required,oneof=ITEM AMOUNT"`
Items []SplitBillItemRequest `json:"items,omitempty" validate:"required_if=Type ITEM,dive"`
Amount float64 `json:"amount,omitempty" validate:"required_if=Type AMOUNT,min=0"`
}
type SplitBillItemRequest struct {
@@ -318,7 +320,7 @@ func (h *Handler) Refund(c *gin.Context) {
Reason: req.Reason,
RefundedAt: order.UpdatedAt.Format("2006-01-02T15:04:05Z"),
CustomerName: order.CustomerName,
PaymentType: h.formatPayment(order.PaymentType, order.PaymentProvider),
PaymentType: response.NewPaymentFormatter().Format(order.PaymentType, order.PaymentProvider),
}
c.JSON(http.StatusOK, response.BaseResponse{
@@ -330,116 +332,30 @@ func (h *Handler) Refund(c *gin.Context) {
func (h *Handler) GetOrderHistory(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
limitStr := c.Query("limit")
offsetStr := c.Query("offset")
status := c.Query("status")
startDateStr := c.Query("start_date")
endDateStr := c.Query("end_date")
searchReq := entity.SearchRequest{}
if status != "" {
searchReq.Status = status
}
limit := 20
if limitStr != "" {
parsedLimit, err := strconv.Atoi(limitStr)
if err == nil && parsedLimit > 0 {
limit = parsedLimit
}
}
if limit > 100 {
limit = 100
}
searchReq.Limit = limit
offset := 0
if offsetStr != "" {
parsedOffset, err := strconv.Atoi(offsetStr)
if err == nil && parsedOffset >= 0 {
offset = parsedOffset
}
}
searchReq.Offset = offset
if startDateStr != "" {
startDate, err := time.Parse(time.RFC3339, startDateStr)
if err == nil {
searchReq.Start = startDate
}
}
// Parse end date if provided
if endDateStr != "" {
endDate, err := time.Parse(time.RFC3339, endDateStr)
if err == nil {
searchReq.End = endDate
}
}
orders, total, err := h.service.GetOrderHistory(ctx, *partnerID, searchReq)
searchReq, err := h.queryParser.ParseSearchRequest(c)
if err != nil {
response.ErrorWrapper(c, err)
return
}
responseData := []response.OrderHistoryResponse{}
for _, order := range orders {
var orderItems []response.OrderItemResponse
for _, item := range order.OrderItems {
orderItems = append(orderItems, response.OrderItemResponse{
ProductID: item.ItemID,
ProductName: item.ItemName,
Price: item.Price,
Quantity: item.Quantity,
Subtotal: item.Price * float64(item.Quantity),
})
}
responseData = append(responseData, response.OrderHistoryResponse{
ID: order.ID,
CustomerName: order.CustomerName,
CustomerID: order.CustomerID,
IsMember: order.IsMemberOrder(),
Status: order.Status,
Amount: order.Amount,
Total: order.Total,
PaymentType: h.formatPayment(order.PaymentType, order.PaymentProvider),
TableNumber: order.TableNumber,
OrderType: order.OrderType,
OrderItems: orderItems,
CreatedAt: order.CreatedAt.Format("2006-01-02T15:04:05Z"),
Tax: order.Tax,
})
orders, total, err := h.service.GetOrderHistory(ctx, *searchReq)
if err != nil {
response.ErrorWrapper(c, err)
return
}
responseData := response.MapOrderHistoryResponse(orders)
pagingMeta := response.NewPaginationHelper().BuildPagingMeta(searchReq.Offset, searchReq.Limit, total)
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: responseData,
PagingMeta: &response.PagingMeta{
Page: offset + 1,
Total: int64(total),
Limit: limit,
},
Success: true,
Status: http.StatusOK,
Data: responseData,
PagingMeta: pagingMeta,
})
}
func (h *Handler) formatPayment(payment, provider string) string {
if payment == "CASH" {
return payment
}
return payment + " " + provider
}
func (h *Handler) GetPaymentMethodAnalysis(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
@@ -501,7 +417,7 @@ func (h *Handler) GetPaymentMethodAnalysis(c *gin.Context) {
paymentBreakdown := make([]PaymentMethodBreakdown, len(paymentAnalysis.PaymentMethodBreakdown))
for i, bd := range paymentAnalysis.PaymentMethodBreakdown {
paymentBreakdown[i] = PaymentMethodBreakdown{
PaymentMethod: h.formatPayment(bd.PaymentType, bd.PaymentProvider),
PaymentMethod: response.NewPaymentFormatter().Format(bd.PaymentType, bd.PaymentProvider),
TotalTransactions: bd.TotalTransactions,
TotalAmount: bd.TotalAmount,
}
@@ -632,7 +548,6 @@ func (h *Handler) GetPopularProducts(c *gin.Context) {
func (h *Handler) GetRefundHistory(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
limitStr := c.Query("limit")
offsetStr := c.Query("offset")
@@ -664,8 +579,6 @@ func (h *Handler) GetRefundHistory(c *gin.Context) {
}
searchReq.Offset = offset
// Set status to REFUNDED to get only refunded orders
searchReq.Status = "REFUNDED"
if startDateStr != "" {
@@ -682,7 +595,7 @@ func (h *Handler) GetRefundHistory(c *gin.Context) {
}
}
orders, total, err := h.service.GetOrderHistory(ctx, *partnerID, searchReq)
orders, total, err := h.service.GetOrderHistory(ctx, searchReq)
if err != nil {
response.ErrorWrapper(c, err)
return
@@ -698,7 +611,7 @@ func (h *Handler) GetRefundHistory(c *gin.Context) {
Status: order.Status,
Amount: order.Amount,
Total: order.Total,
PaymentType: h.formatPayment(order.PaymentType, order.PaymentProvider),
PaymentType: response.NewPaymentFormatter().Format(order.PaymentType, order.PaymentProvider),
TableNumber: order.TableNumber,
OrderType: order.OrderType,
CreatedAt: order.CreatedAt.Format("2006-01-02T15:04:05Z"),
@@ -759,7 +672,6 @@ func (h *Handler) PartialRefund(c *gin.Context) {
return
}
// Calculate refunded amount
refundedAmount := 0.0
var refundedItems []RefundedItemResponse
@@ -789,7 +701,7 @@ func (h *Handler) PartialRefund(c *gin.Context) {
Reason: req.Reason,
RefundedAt: order.UpdatedAt.Format("2006-01-02T15:04:05Z"),
CustomerName: order.CustomerName,
PaymentType: h.formatPayment(order.PaymentType, order.PaymentProvider),
PaymentType: response.NewPaymentFormatter().Format(order.PaymentType, order.PaymentProvider),
RefundedItems: refundedItems,
}
@@ -815,7 +727,6 @@ func (h *Handler) VoidOrder(c *gin.Context) {
return
}
// Convert request items to entity items
var items []entity.VoidItem
if req.Type == "ITEM" {
items = make([]entity.VoidItem, len(req.Items))
@@ -906,7 +817,8 @@ func (h *Handler) SplitBill(c *gin.Context) {
}
}
splitOrder, err := h.service.SplitBillRequest(ctx, *ctx.GetPartnerID(), req.OrderID, req.Type, req.PaymentMethod, req.PaymentProvider, items, req.Amount)
splitOrder, err := h.service.SplitBillRequest(ctx,
*ctx.GetPartnerID(), req.OrderID, req.Type, items, req.Amount)
if err != nil {
response.ErrorWrapper(c, err)
return
@@ -918,3 +830,26 @@ func (h *Handler) SplitBill(c *gin.Context) {
Data: response.MapToOrderResponse(&entity.OrderResponse{Order: splitOrder}),
})
}
func (h *Handler) GetByID(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
orderID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
order, err := h.service.GetOrderByIDAndPartnerID(ctx, orderID, *partnerID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToOrderResponse(&entity.OrderResponse{Order: order}),
})
}