update
This commit is contained in:
@@ -109,7 +109,7 @@ func MapOrderToCreateOrderResponse(orderResponse *entity.OrderResponse, req requ
|
||||
PaymentType: order.PaymentType,
|
||||
CreatedAt: order.CreatedAt,
|
||||
OrderItems: orderItems,
|
||||
Fee: order.Fee,
|
||||
Tax: order.Tax,
|
||||
Total: order.Total,
|
||||
}
|
||||
}
|
||||
@@ -249,7 +249,7 @@ func (h *Handler) toOrderDetail(order *entity.Order) *response.OrderDetail {
|
||||
PaymentLink: paymentLink,
|
||||
PaymentToken: paymentToken,
|
||||
SiteName: siteName,
|
||||
Fee: order.Fee,
|
||||
Fee: order.Tax,
|
||||
}
|
||||
|
||||
orderDetail.OrderItems = make([]response.OrderDetailItem, len(order.OrderItems))
|
||||
|
||||
@@ -38,7 +38,7 @@ type CreateInProgressOrderRequest struct {
|
||||
OrderType string `json:"order_type"`
|
||||
PaymentProvider string `json:"payment_provider"`
|
||||
TableNumber string `json:"table_number"`
|
||||
InProgressOrderID string `json:"in_progress_order_id"`
|
||||
InProgressOrderID int64 `json:"in_progress_order_id"`
|
||||
}
|
||||
|
||||
type InProgressOrderItemRequest struct {
|
||||
@@ -72,15 +72,15 @@ func (h *InProgressOrderHandler) Save(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
orderItems := make([]entity.InProgressOrderItem, len(req.OrderItems))
|
||||
orderItems := make([]entity.OrderItemRequest, len(req.OrderItems))
|
||||
for i, item := range req.OrderItems {
|
||||
orderItems[i] = entity.InProgressOrderItem{
|
||||
ItemID: item.ProductID,
|
||||
Quantity: item.Quantity,
|
||||
orderItems[i] = entity.OrderItemRequest{
|
||||
ProductID: item.ProductID,
|
||||
Quantity: item.Quantity,
|
||||
}
|
||||
}
|
||||
|
||||
order := &entity.InProgressOrder{
|
||||
order := &entity.OrderRequest{
|
||||
PartnerID: *partnerID,
|
||||
CustomerID: req.CustomerID,
|
||||
CustomerName: req.CustomerName,
|
||||
@@ -89,6 +89,7 @@ func (h *InProgressOrderHandler) Save(c *gin.Context) {
|
||||
TableNumber: req.TableNumber,
|
||||
OrderType: req.OrderType,
|
||||
ID: req.InProgressOrderID,
|
||||
Source: "POS",
|
||||
}
|
||||
|
||||
_, err := h.service.Save(ctx, order)
|
||||
@@ -103,7 +104,7 @@ func (h *InProgressOrderHandler) Save(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func mapToInProgressOrderResponse(order *entity.InProgressOrder) map[string]interface{} {
|
||||
func mapToInProgressOrderResponse(order *entity.Order) map[string]interface{} {
|
||||
orderItems := make([]map[string]interface{}, len(order.OrderItems))
|
||||
for i, item := range order.OrderItems {
|
||||
orderItems[i] = map[string]interface{}{
|
||||
|
||||
@@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"enaklo-pos-be/internal/common/errors"
|
||||
order2 "enaklo-pos-be/internal/constants/order"
|
||||
"enaklo-pos-be/internal/entity"
|
||||
"enaklo-pos-be/internal/handlers/request"
|
||||
"enaklo-pos-be/internal/handlers/response"
|
||||
@@ -9,6 +10,8 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
@@ -26,6 +29,12 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
|
||||
|
||||
route.POST("/inquiry", jwt, h.Inquiry)
|
||||
route.POST("/execute", jwt, h.Execute)
|
||||
route.GET("/history", jwt, h.GetOrderHistory)
|
||||
route.GET("/payment-analysis", jwt, h.GetPaymentMethodAnalysis)
|
||||
route.GET("/revenue-overview", jwt, h.GetRevenueOverview)
|
||||
route.GET("/sales-by-category", jwt, h.GetSalesByCategory)
|
||||
route.GET("/popular-products", jwt, h.GetPopularProducts)
|
||||
|
||||
}
|
||||
|
||||
type InquiryRequest struct {
|
||||
@@ -56,7 +65,7 @@ type OrderItemRequest struct {
|
||||
type ExecuteRequest struct {
|
||||
PaymentMethod string `json:"payment_method" validate:"required"`
|
||||
PaymentProvider string `json:"payment_provider"`
|
||||
InProgressOrderID string `json:"in_progress_order_id"`
|
||||
InProgressOrderID int64 `json:"in_progress_order_id"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
@@ -140,3 +149,307 @@ func (h *Handler) Execute(c *gin.Context) {
|
||||
Data: response.MapToOrderResponse(result),
|
||||
})
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
// Build search request
|
||||
searchReq := entity.SearchRequest{}
|
||||
|
||||
// Set status if provided
|
||||
if status != "" {
|
||||
searchReq.Status = status
|
||||
}
|
||||
|
||||
// Parse and set limit
|
||||
limit := 10
|
||||
if limitStr != "" {
|
||||
parsedLimit, err := strconv.Atoi(limitStr)
|
||||
if err == nil && parsedLimit > 0 {
|
||||
limit = parsedLimit
|
||||
}
|
||||
}
|
||||
if limit > 20 {
|
||||
limit = 20
|
||||
}
|
||||
searchReq.Limit = limit
|
||||
|
||||
// Parse and set offset
|
||||
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)
|
||||
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,
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: responseData,
|
||||
PagingMeta: &response.PagingMeta{
|
||||
Page: offset + 1,
|
||||
Total: int64(total),
|
||||
Limit: limit,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
// Parse query parameters
|
||||
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{}
|
||||
|
||||
limit := 10
|
||||
if limitStr != "" {
|
||||
parsedLimit, err := strconv.Atoi(limitStr)
|
||||
if err == nil && parsedLimit > 0 {
|
||||
limit = parsedLimit
|
||||
}
|
||||
}
|
||||
if limit > 20 {
|
||||
limit = 20
|
||||
}
|
||||
searchReq.Limit = limit
|
||||
|
||||
offset := 0
|
||||
if offsetStr != "" {
|
||||
parsedOffset, err := strconv.Atoi(offsetStr)
|
||||
if err == nil && parsedOffset >= 0 {
|
||||
offset = parsedOffset
|
||||
}
|
||||
}
|
||||
searchReq.Offset = offset
|
||||
|
||||
if status != "" {
|
||||
searchReq.Status = status
|
||||
}
|
||||
|
||||
if startDateStr != "" {
|
||||
startDate, err := time.Parse(time.RFC3339, startDateStr)
|
||||
if err == nil {
|
||||
searchReq.Start = startDate
|
||||
}
|
||||
}
|
||||
|
||||
if endDateStr != "" {
|
||||
endDate, err := time.Parse(time.RFC3339, endDateStr)
|
||||
if err == nil {
|
||||
searchReq.End = endDate
|
||||
}
|
||||
}
|
||||
|
||||
paymentAnalysis, err := h.service.GetOrderPaymentAnalysis(ctx, *partnerID, searchReq)
|
||||
if err != nil {
|
||||
response.ErrorWrapper(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
paymentBreakdown := make([]PaymentMethodBreakdown, len(paymentAnalysis.PaymentMethodBreakdown))
|
||||
for i, bd := range paymentAnalysis.PaymentMethodBreakdown {
|
||||
paymentBreakdown[i] = PaymentMethodBreakdown{
|
||||
PaymentMethod: h.formatPayment(bd.PaymentType, bd.PaymentProvider),
|
||||
TotalTransactions: bd.TotalTransactions,
|
||||
TotalAmount: bd.TotalAmount,
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: PaymentMethodAnalysisResponse{
|
||||
PaymentMethodBreakdown: paymentBreakdown,
|
||||
TotalAmount: paymentAnalysis.TotalAmount,
|
||||
TotalTransactions: paymentAnalysis.TotalTransactions,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type PaymentMethodBreakdown struct {
|
||||
PaymentMethod string `json:"payment_method"`
|
||||
TotalTransactions int64 `json:"total_transactions"`
|
||||
TotalAmount float64 `json:"total_amount"`
|
||||
AverageTransactionAmount float64 `json:"average_transaction_amount"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
}
|
||||
|
||||
type PaymentMethodAnalysisResponse struct {
|
||||
PaymentMethodBreakdown []PaymentMethodBreakdown `json:"payment_method_breakdown"`
|
||||
TotalAmount float64 `json:"total_amount"`
|
||||
TotalTransactions int64 `json:"total_transactions"`
|
||||
|
||||
MostUsedPaymentMethod string `json:"most_used_payment_method"`
|
||||
HighestRevenueMethod string `json:"highest_revenue_method"`
|
||||
}
|
||||
|
||||
func (h *Handler) GetRevenueOverview(c *gin.Context) {
|
||||
ctx := request.GetMyContext(c)
|
||||
partnerID := ctx.GetPartnerID()
|
||||
|
||||
granularity := c.Query("period")
|
||||
|
||||
year := time.Now().Year()
|
||||
|
||||
if granularity != "m" && granularity != "w" && granularity != "d" {
|
||||
granularity = "m"
|
||||
}
|
||||
|
||||
revenueOverview, err := h.service.GetRevenueOverview(
|
||||
ctx,
|
||||
*partnerID,
|
||||
year,
|
||||
granularity,
|
||||
order2.Paid.String(),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
response.ErrorWrapper(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: revenueOverview,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) GetSalesByCategory(c *gin.Context) {
|
||||
ctx := request.GetMyContext(c)
|
||||
partnerID := ctx.GetPartnerID()
|
||||
|
||||
period := c.Query("period")
|
||||
status := order2.Paid.String()
|
||||
|
||||
if period != "d" && period != "w" && period != "m" {
|
||||
period = "d"
|
||||
}
|
||||
|
||||
salesByCategory, err := h.service.GetSalesByCategory(
|
||||
ctx,
|
||||
*partnerID,
|
||||
period,
|
||||
status,
|
||||
)
|
||||
if err != nil {
|
||||
response.ErrorWrapper(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: salesByCategory,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Handler) GetPopularProducts(c *gin.Context) {
|
||||
ctx := request.GetMyContext(c)
|
||||
partnerID := ctx.GetPartnerID()
|
||||
|
||||
period := c.Query("period")
|
||||
status := order2.Paid.String()
|
||||
limitStr := c.Query("limit")
|
||||
sortBy := c.Query("sort_by")
|
||||
|
||||
limit, err := strconv.Atoi(limitStr)
|
||||
if err != nil {
|
||||
limit = 10 // default limit
|
||||
}
|
||||
|
||||
if period != "d" && period != "w" && period != "m" {
|
||||
period = "d"
|
||||
}
|
||||
|
||||
popularProducts, err := h.service.GetPopularProducts(
|
||||
ctx,
|
||||
*partnerID,
|
||||
period,
|
||||
status,
|
||||
limit,
|
||||
sortBy,
|
||||
)
|
||||
if err != nil {
|
||||
response.ErrorWrapper(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: popularProducts,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ func MapOrderToCreateOrderResponse(orderResponse *entity.OrderResponse) response
|
||||
Status: order.Status,
|
||||
Amount: order.Amount,
|
||||
Total: order.Total,
|
||||
Fee: order.Fee,
|
||||
Tax: order.Tax,
|
||||
PaymentType: order.PaymentType,
|
||||
CreatedAt: order.CreatedAt,
|
||||
OrderItems: orderItems,
|
||||
|
||||
@@ -28,6 +28,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
|
||||
route.PUT("/:id", jwt, isSuperAdmin, h.Update)
|
||||
route.GET("/:id", jwt, isSuperAdmin, h.GetByID)
|
||||
route.DELETE("/:id", jwt, isSuperAdmin, h.Delete)
|
||||
route.PUT("/update", jwt, h.UpdateMyStore)
|
||||
}
|
||||
|
||||
func NewHandler(service services.Partner) *Handler {
|
||||
@@ -268,3 +269,27 @@ func (h *Handler) toPartnerResponseList(resp []*entity.Partner, total int64, req
|
||||
Offset: req.Offset,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateMyStore(c *gin.Context) {
|
||||
ctx := request.GetMyContext(c)
|
||||
|
||||
PartnerID := ctx.GetPartnerID()
|
||||
|
||||
var req request.Partner
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.ErrorWrapper(c, errors.ErrorBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
updatedPartner, err := h.service.Update(ctx, req.ToEntityUpdate(*PartnerID))
|
||||
if err != nil {
|
||||
response.ErrorWrapper(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.BaseResponse{
|
||||
Success: true,
|
||||
Status: http.StatusOK,
|
||||
Data: h.toPartnerResponse(updatedPartner),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ type CreateOrderResponse struct {
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
Total float64 `json:"total"`
|
||||
Fee float64 `json:"fee"`
|
||||
Tax float64 `json:"tax"`
|
||||
PaymentType string `json:"payment_type"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
OrderItems []CreateOrderItemResponse `json:"order_items"`
|
||||
@@ -187,3 +187,17 @@ type OrderDetailItem struct {
|
||||
UnitPrice float64 `json:"unit_price"` // Price per unit
|
||||
TotalPrice float64 `json:"total_price"` // Total price for this item (Quantity * UnitPrice)
|
||||
}
|
||||
|
||||
type OrderHistoryResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
CustomerName string `json:"customer_name"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
Total float64 `json:"total"`
|
||||
PaymentType string `json:"payment_type"`
|
||||
TableNumber string `json:"table_number"`
|
||||
OrderType string `json:"order_type"`
|
||||
OrderItems []OrderItemResponse `json:"order_items"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Tax float64 `json:"tax"`
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ type OrderInquiryResponse struct {
|
||||
ID string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
Tax float64 `json:"tax"`
|
||||
Total float64 `json:"total"`
|
||||
CustomerID int64 `json:"customer_id"`
|
||||
PaymentType string `json:"payment_type"`
|
||||
@@ -54,7 +54,7 @@ func MapToInquiryResponse(result *entity.OrderInquiryResponse) OrderInquiryRespo
|
||||
ID: result.OrderInquiry.ID,
|
||||
Status: result.OrderInquiry.Status,
|
||||
Amount: result.OrderInquiry.Amount,
|
||||
Fee: result.OrderInquiry.Fee,
|
||||
Tax: result.OrderInquiry.Tax,
|
||||
Total: result.OrderInquiry.Total,
|
||||
CustomerID: result.OrderInquiry.CustomerID,
|
||||
PaymentType: result.OrderInquiry.PaymentType,
|
||||
@@ -74,7 +74,7 @@ type OrderResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
Tax float64 `json:"tax"`
|
||||
Total float64 `json:"total"`
|
||||
CustomerName string `json:"customer_name,omitempty"`
|
||||
PaymentType string `json:"payment_type"`
|
||||
@@ -89,7 +89,7 @@ func MapToOrderResponse(result *entity.OrderResponse) OrderResponse {
|
||||
ID: result.Order.ID,
|
||||
Status: result.Order.Status,
|
||||
Amount: result.Order.Amount,
|
||||
Fee: result.Order.Fee,
|
||||
Tax: result.Order.Tax,
|
||||
Total: result.Order.Total,
|
||||
PaymentType: result.Order.PaymentType,
|
||||
CreatedAt: result.Order.CreatedAt,
|
||||
|
||||
@@ -3,5 +3,5 @@ package response
|
||||
type PagingMeta struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
Total int64 `json:"total_data"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user