Add refund order

This commit is contained in:
aditya.siregar
2025-06-14 21:17:13 +07:00
parent 58d3b32c40
commit ebb33186b8
42 changed files with 1152 additions and 2094 deletions
+123
View File
@@ -0,0 +1,123 @@
package http
import (
"enaklo-pos-be/internal/common/errors"
"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"
)
type CashierSessionHandler struct {
service cashier_session.Service
}
func NewCashierSession(service cashier_session.Service) *CashierSessionHandler {
return &CashierSessionHandler{service: service}
}
func (h *CashierSessionHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/cashier-sessions")
route.Use(jwt)
route.POST("/open", h.OpenSession)
route.POST("/close/:id", h.CloseSession)
route.GET("/open", h.GetOpenSession)
route.GET("/report/:id", h.GetSessionReport)
}
func (h *CashierSessionHandler) OpenSession(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.OpenCashierSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
session, err := h.service.OpenSession(ctx, req.ToEntity(ctx.RequestedBy()))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCashierSessionResponse(session),
})
}
func (h *CashierSessionHandler) CloseSession(c *gin.Context) {
ctx := request.GetMyContext(c)
idStr := c.Param("id")
sessionID, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
var body struct {
ClosingAmount float64 `json:"closing_amount"`
}
if err := c.ShouldBindJSON(&body); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
report, err := h.service.CloseSession(ctx, sessionID, body.ClosingAmount)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCashierSessionReport(report),
})
}
func (h *CashierSessionHandler) GetOpenSession(c *gin.Context) {
ctx := request.GetMyContext(c)
cashierID := ctx.RequestedBy()
session, err := h.service.GetOpenSession(ctx, cashierID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCashierSessionResponse(session),
})
}
func (h *CashierSessionHandler) GetSessionReport(c *gin.Context) {
ctx := request.GetMyContext(c)
idStr := c.Param("id")
sessionID, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
report, err := h.service.GetSessionReport(ctx, sessionID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCashierSessionReport(report),
})
}
+139
View File
@@ -0,0 +1,139 @@
package http
import (
"enaklo-pos-be/internal/common/errors"
"enaklo-pos-be/internal/handlers/request"
"enaklo-pos-be/internal/handlers/response"
category "enaklo-pos-be/internal/services/v2/categories"
"github.com/gin-gonic/gin"
"net/http"
"strconv"
)
type CategoryHandler struct {
service category.Service
}
func NewCategoryHandler(service category.Service) *CategoryHandler {
return &CategoryHandler{service: service}
}
func (h *CategoryHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/categories")
route.Use(jwt)
route.POST("/create", h.Create)
route.GET("/list", h.GetByPartner)
route.GET("/:id", h.GetByID)
route.PUT("/:id", h.Update)
route.DELETE("/:id", h.Delete)
}
func (h *CategoryHandler) Create(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.CategoryRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
category, err := h.service.Create(ctx, req.ToEntity(ctx.RequestedBy()))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCategoryResponse(category),
})
}
func (h *CategoryHandler) GetByPartner(c *gin.Context) {
ctx := request.GetMyContext(c)
categories, err := h.service.GetByPartnerID(ctx, ctx.RequestedBy())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCategoryListResponse(categories),
})
}
func (h *CategoryHandler) GetByID(c *gin.Context) {
ctx := request.GetMyContext(c)
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
category, err := h.service.GetByID(ctx, id)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.MapToCategoryResponse(category),
})
}
func (h *CategoryHandler) Update(c *gin.Context) {
ctx := request.GetMyContext(c)
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
var req request.CategoryRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
category := req.ToEntity(ctx.RequestedBy())
category.ID = id
if err := h.service.Update(ctx, category); err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
})
}
func (h *CategoryHandler) Delete(c *gin.Context) {
ctx := request.GetMyContext(c)
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if err := h.service.Delete(ctx, id); err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
})
}
@@ -1,268 +0,0 @@
package customerorder
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"
"encoding/json"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
type Handler struct {
service services.Order
}
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/order")
route.POST("/inquiry", h.Inquiry)
route.POST("/execute", jwt, h.Execute)
route.GET("/history", jwt, h.History)
route.GET("/detail", jwt, h.Detail)
}
func NewHandler(service services.Order) *Handler {
return &Handler{
service: service,
}
}
func (h *Handler) Inquiry(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.CustomerOrder
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if err := request.ValidateAndHandleError(req); err != nil {
response.ErrorWrapper(c, errors.NewErrorMessage(errors.ErrorBadRequest, err.Error()))
return
}
order, err := h.service.CreateOrder(ctx, req.ToEntity(ctx.RequestedBy()))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToCreateOrderResponse(order, req),
})
}
func (h *Handler) Execute(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.Execute
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
}
order, err := h.service.Execute(ctx, req.ToOrderExecuteRequest(ctx.RequestedBy()))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToExecuteOrderResponse(order),
})
}
func MapOrderToCreateOrderResponse(orderResponse *entity.OrderResponse, req request.CustomerOrder) response.CreateOrderResponse {
order := orderResponse.Order
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.CreateOrderResponse{
ID: order.ID,
PartnerID: order.PartnerID,
Status: order.Status,
Amount: order.Amount,
PaymentType: order.PaymentType,
CreatedAt: order.CreatedAt,
OrderItems: orderItems,
Tax: order.Tax,
Total: order.Total,
}
}
func MapOrderToExecuteOrderResponse(orderResponse *entity.ExecuteOrderResponse) response.ExecuteOrderResponse {
order := orderResponse.Order
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.ExecuteOrderResponse{
ID: order.ID,
PartnerID: order.PartnerID,
Status: order.Status,
Amount: order.Amount,
PaymentType: order.PaymentType,
CreatedAt: order.CreatedAt,
OrderItems: orderItems,
PaymentToken: orderResponse.PaymentToken,
RedirectURL: orderResponse.RedirectURL,
QRcode: orderResponse.QRCode,
VirtualAccount: orderResponse.VirtualAccount,
BankName: orderResponse.BankName,
BankCode: orderResponse.BankCode,
}
}
func (h *Handler) toHistoryOrderResponse(resp *entity.HistoryOrder) response.HistoryOrder {
return response.HistoryOrder{
ID: resp.ID,
Employee: resp.Employee,
Site: resp.Site,
Timestamp: resp.Timestamp.Format(time.RFC3339),
BookingTime: resp.BookingTime.Format(time.RFC3339),
Tickets: resp.Tickets,
PaymentType: resp.PaymentType,
Status: resp.GetPaymentStatus(),
Amount: resp.Amount,
}
}
func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.OrderParamCustomer) response.HistoryOrderList {
var orders []response.HistoryOrder
for _, b := range resp {
orders = append(orders, h.toHistoryOrderResponse(b))
}
return response.HistoryOrderList{
Orders: orders,
Total: total,
Limit: req.Limit,
Offset: req.Offset,
}
}
func (h *Handler) History(c *gin.Context) {
var req request.OrderParamCustomer
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
orders, total, err := h.service.GetAllHistoryOrders(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toHistoryOrderList(orders, int64(total), req),
})
}
func (h *Handler) Detail(c *gin.Context) {
var req request.OrderParamCustomer
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
order, err := h.service.GetByID(ctx, req.ID, req.ReferenceID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toOrderDetail(order),
})
}
func (h *Handler) toOrderDetail(order *entity.Order) *response.OrderDetail {
if order == nil {
return nil
}
payment := map[string]string{}
paymentLink := ""
paymentToken := ""
if order.Payment.RequestMetadata != nil && order.Status != "EXPIRED" {
json.Unmarshal(order.Payment.RequestMetadata, &payment)
paymentLink = payment["payment_redirect_url"]
paymentToken = payment["payment_token"]
}
qrCode := ""
var siteName string
if order.Site != nil {
siteName = order.Site.Name
}
orderDetail := &response.OrderDetail{
ID: order.ID,
QRCode: qrCode,
FullName: order.User.Name,
Email: order.User.Email,
PhoneNumber: order.User.PhoneNumber,
TotalAmount: order.Total,
CreatedAt: order.CreatedAt,
Status: order.Status,
PaymentLink: paymentLink,
PaymentToken: paymentToken,
SiteName: siteName,
Fee: order.Tax,
}
orderDetail.OrderItems = make([]response.OrderDetailItem, len(order.OrderItems))
for i, item := range order.OrderItems {
orderDetail.OrderItems[i] = response.OrderDetailItem{
Name: item.Product.Name,
ItemType: item.ItemType,
Description: "",
Quantity: int(item.Quantity),
UnitPrice: item.Price,
TotalPrice: float64(item.Quantity) * item.Price,
}
}
return orderDetail
}
@@ -1,229 +0,0 @@
package discovery
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"
"github.com/gin-gonic/gin"
"net/http"
)
type Handler struct {
service services.DiscoverService
}
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/discovery")
route.GET("/home", h.DisoveryHome)
route.GET("/search", h.DisoverySearch)
route.GET("/site/detail", h.DiscoveryGetByID)
route.GET("/site/products", h.DiscoveryProducts)
}
func NewHandler(service services.DiscoverService) *Handler {
return &Handler{
service: service,
}
}
func (h *Handler) DisoveryHome(c *gin.Context) {
var req request.DiscoveryHomeParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.Home(c.Request.Context(), req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: ConvertEntityToResponse(res),
})
}
func (h *Handler) DisoverySearch(c *gin.Context) {
var req request.DiscoveryHomeParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, total, err := h.service.Search(c.Request.Context(), req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: ConvertEntityToSearchResponse(res, total, req),
})
}
func (h *Handler) DiscoveryGetByID(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.DiscoverySearchByID
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.GetByID(ctx, req.ID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: ConvertEntityToGetByIDResp(res),
})
}
func (h *Handler) DiscoveryProducts(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.DiscoverySearchByID
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.GetProductsByID(ctx, req.ID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: ConvertToProductResp(res),
})
}
func ConvertEntityToResponse(entityResp *entity.DiscoverySearchResp) *response.ExploreResponse {
// Convert ExploreRegions
exploreRegions := make([]response.Region, len(entityResp.ExploreRegions))
for i, region := range entityResp.ExploreRegions {
exploreRegions[i] = response.Region{
Name: region.Name,
}
}
// Convert ExploreDestinations
exploreDestinations := make([]response.Destination, len(entityResp.ExploreDestinations))
for i, destination := range entityResp.ExploreDestinations {
exploreDestinations[i] = response.Destination{
Name: destination.Name,
ImageURL: destination.ImageURL,
}
}
mustVisit := make([]response.MustVisit, len(entityResp.MustVisit))
for i, mv := range entityResp.MustVisit {
mustVisit[i] = response.MustVisit{
Name: mv.Name,
Region: mv.Region,
Rating: mv.Rating,
ReviewCount: mv.ReviewCount,
Price: mv.Price,
ImageURL: mv.ImageURL,
SiteID: mv.SiteID,
Regency: mv.Regency,
}
}
return &response.ExploreResponse{
ExploreRegions: exploreRegions,
ExploreDestinations: exploreDestinations,
MustVisit: mustVisit,
}
}
func ConvertEntityToSearchResponse(entityResp *entity.DiscoverySearchResp, total int64, req request.DiscoveryHomeParam) *response.SearchResponse {
data := make([]response.SiteSeach, len(entityResp.MustVisit))
for i, mv := range entityResp.MustVisit {
data[i] = response.SiteSeach{
Name: mv.Name,
Region: mv.Region,
Rating: mv.Rating,
ReviewCount: mv.ReviewCount,
Price: mv.Price,
ImageURL: mv.ImageURL,
SiteID: mv.SiteID,
Regency: mv.Regency,
}
}
return &response.SearchResponse{
Data: data,
Total: int(total),
Limit: req.Limit,
Offset: req.Offset,
}
}
func ConvertEntityToGetByIDResp(resp *entity.Site) *response.SearchSiteByIDResponse {
if resp == nil {
return nil
}
return &response.SearchSiteByIDResponse{
ID: resp.ID,
Name: resp.Name,
Image: resp.Image,
Address: resp.Address,
LocationLink: resp.LocationLink,
Description: resp.Description,
Highlight: resp.Highlight,
ContactPerson: resp.ContactPerson,
TnC: resp.TnC,
AdditionalInfo: resp.AdditionalInfo,
PartnerID: resp.PartnerID,
Regency: resp.Regency,
Region: resp.Region,
}
}
func ConvertToProductResp(resp []*entity.Product) *response.SearchProductSiteResponse {
if resp == nil {
return nil
}
var productResp []response.SearchProductSiteByIDResponse
partnerID := int64(0)
for _, res := range resp {
productResp = append(productResp, response.SearchProductSiteByIDResponse{
ID: res.ID,
Name: res.Name,
Price: res.Price,
Description: res.Description,
Type: res.Type,
})
partnerID = res.PartnerID
}
return &response.SearchProductSiteResponse{
Product: productResp,
PartnerID: partnerID,
}
}
-205
View File
@@ -1,205 +0,0 @@
package event
import (
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"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"
)
type Handler struct {
service services.Event
}
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/event")
route.POST("/", jwt, h.Create)
route.GET("/list", jwt, h.GetAll)
route.PUT("/:id", jwt, h.Update)
route.GET("/:id", jwt, h.GetByID)
route.DELETE("/:id", jwt, h.Delete)
}
func NewHandler(service services.Event) *Handler {
return &Handler{
service: service,
}
}
func (h *Handler) Create(c *gin.Context) {
var req request.Event
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if err := req.Validate(); err != nil {
response.ErrorWrapper(c, errors.ErrorInvalidRequest)
return
}
res, err := h.service.Create(c.Request.Context(), req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toEventResponse(res),
})
}
func (h *Handler) Update(c *gin.Context) {
id := c.Param("id")
eventID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
var req request.Event
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if err := req.Validate(); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
updatedEvent, err := h.service.Update(c.Request.Context(), eventID, req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toEventResponse(updatedEvent),
})
}
func (h *Handler) GetAll(c *gin.Context) {
var req request.EventParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
events, total, err := h.service.GetAll(c.Request.Context(), req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toEventResponseList(events, int64(total), req),
})
}
func (h *Handler) Delete(c *gin.Context) {
id := c.Param("id")
// Parse the ID into a uint
eventID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
err = h.service.Delete(c.Request.Context(), eventID)
if err != nil {
c.JSON(http.StatusInternalServerError, response.BaseResponse{
Success: false,
Status: http.StatusInternalServerError,
Message: err.Error(),
Data: nil,
})
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: nil,
})
}
func (h *Handler) GetByID(c *gin.Context) {
id := c.Param("id")
// Parse the ID into a uint
eventID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.GetByID(c.Request.Context(), eventID)
if err != nil {
c.JSON(http.StatusInternalServerError, response.BaseResponse{
Success: false,
Status: http.StatusInternalServerError,
Message: err.Error(),
Data: nil,
})
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toEventResponse(res),
})
}
func (h *Handler) toEventResponse(resp *entity.Event) response.Event {
return response.Event{
ID: resp.ID,
Name: resp.Name,
Description: resp.Description,
StartDate: resp.StartDate.Format("2006-01-02"),
EndDate: resp.EndDate.Format("2006-01-02"),
StartTime: resp.StartDate.Format("15:04:05"),
EndTime: resp.EndDate.Format("15:04:05"),
Location: resp.Location,
Level: resp.Level,
Included: resp.Included,
Price: resp.Price,
Paid: resp.Paid,
LocationID: resp.LocationID,
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
Status: string(resp.Status),
}
}
func (h *Handler) toEventResponseList(resp []*entity.Event, total int64, req request.EventParam) response.EventList {
var events []response.Event
for _, evt := range resp {
events = append(events, h.toEventResponse(evt))
}
return response.EventList{
Events: events,
Total: total,
Limit: req.Limit,
Offset: req.Offset,
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ func (h *MenuHandler) GetProducts(c *gin.Context) {
return
}
searchParam := req.ToEntity()
searchParam := req.ToEntity(partnerID)
searchParam.PartnerID = partnerID
products, total, err := h.service.GetProductsByPartnerID(ctx, searchParam)
+35
View File
@@ -29,6 +29,7 @@ func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route.POST("/inquiry", jwt, h.Inquiry)
route.POST("/execute", jwt, h.Execute)
route.POST("/refund", jwt, h.Refund)
route.GET("/history", jwt, h.GetOrderHistory)
route.GET("/payment-analysis", jwt, h.GetPaymentMethodAnalysis)
route.GET("/revenue-overview", jwt, h.GetRevenueOverview)
@@ -47,6 +48,7 @@ type InquiryRequest struct {
OrderType string `json:"order_type"`
PaymentProvider string `json:"payment_provider"`
TableNumber string `json:"table_number"`
CashierSessionID int64 `json:"cashier_session_id"`
}
func (o *InquiryRequest) GetPaymentProvider() string {
@@ -70,6 +72,11 @@ type ExecuteRequest struct {
Token string `json:"token"`
}
type RefundRequest struct {
OrderID int64 `json:"order_id" validate:"required"`
Reason string `json:"reason" validate:"required"`
}
func (h *Handler) Inquiry(c *gin.Context) {
ctx := request.GetMyContext(c)
userID := ctx.RequestedBy()
@@ -109,6 +116,7 @@ func (h *Handler) Inquiry(c *gin.Context) {
OrderType: req.OrderType,
PaymentProvider: req.GetPaymentProvider(),
TableNumber: req.TableNumber,
CashierSessionID: req.CashierSessionID,
}
result, err := h.service.CreateOrderInquiry(ctx, orderReq)
@@ -152,6 +160,33 @@ func (h *Handler) Execute(c *gin.Context) {
})
}
func (h *Handler) Refund(c *gin.Context) {
ctx := request.GetMyContext(c)
var req RefundRequest
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
}
err := h.service.RefundRequest(ctx, *ctx.GetPartnerID(), req.OrderID, req.Reason)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
})
}
func (h *Handler) GetOrderHistory(c *gin.Context) {
ctx := request.GetMyContext(c)
partnerID := ctx.GetPartnerID()
-461
View File
@@ -1,461 +0,0 @@
package order
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"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
type Handler struct {
service services.Order
}
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/order")
route.POST("/inquiry", jwt, h.Inquiry)
route.GET("/print-detail", jwt, h.PrintDetail)
route.POST("/execute", jwt, h.Execute)
route.GET("/history", jwt, h.GetAllHistoryOrders)
route.GET("/ticket-sold", jwt, h.CountSoldOfTicket)
route.POST("/checkin/inquiry", jwt, h.CheckInInquiry)
route.POST("/checkin/execute", jwt, h.CheckInExecute)
route.GET("/sum-amount", jwt, h.SumAmount)
route.GET("/daily-sales", jwt, h.GetDailySalesTicket)
route.GET("/payment-distribution", jwt, h.GetPaymentDistributionChart)
}
func NewHandler(service services.Order) *Handler {
return &Handler{
service: service,
}
}
func (h *Handler) Inquiry(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.Order
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
}
orderRequest := req.ToEntity(*ctx.GetPartnerID(), ctx.RequestedBy())
order, err := h.service.CreateOrder(ctx, orderRequest)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToCreateOrderResponse(order),
})
}
func (h *Handler) PrintDetail(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.OrderPrintDetail
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
order, err := h.service.GetPrintDetail(ctx, req.ID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToPrintDetailResponse(order, ctx.GetName()),
})
}
func (h *Handler) Execute(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.Execute
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if !ctx.IsCasheer() {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
req.PartnerID = *ctx.GetPartnerID()
validate := validator.New()
if err := validate.Struct(req); err != nil {
response.ErrorWrapper(c, err)
return
}
order, err := h.service.Execute(ctx, req.ToOrderExecuteRequest(ctx.RequestedBy()))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToExecuteOrderResponse(order),
})
}
func (h *Handler) CheckInInquiry(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.Checkin
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if !ctx.IsCasheer() || req.QRCode == "" {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
partnerID := ctx.GetPartnerID()
resp, err := h.service.CheckInInquiry(ctx, req.QRCode, partnerID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.CheckingInquiryResponse{
Token: resp.Token,
},
})
}
func (h *Handler) CheckInExecute(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.CheckinExecute
if err := c.ShouldBindJSON(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
if !ctx.IsCasheer() || req.Token == "" {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
partnerID := ctx.GetPartnerID()
resp, err := h.service.CheckInExecute(ctx, req.Token, partnerID)
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: MapOrderToExecuteCheckinResponse(resp.Order),
})
}
func MapOrderToCreateOrderResponse(orderResponse *entity.OrderResponse) response.CreateOrderResponse {
order := orderResponse.Order
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.CreateOrderResponse{
ID: order.ID,
PartnerID: order.PartnerID,
Status: order.Status,
Amount: order.Amount,
Total: order.Total,
Tax: order.Tax,
PaymentType: order.PaymentType,
CreatedAt: order.CreatedAt,
OrderItems: orderItems,
}
}
func MapOrderToExecuteOrderResponse(orderResponse *entity.ExecuteOrderResponse) response.ExecuteOrderResponse {
order := orderResponse.Order
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.ExecuteOrderResponse{
ID: order.ID,
PartnerID: order.PartnerID,
Status: order.Status,
Amount: order.Amount,
PaymentType: order.PaymentType,
CreatedAt: order.CreatedAt,
OrderItems: orderItems,
PaymentToken: orderResponse.PaymentToken,
RedirectURL: orderResponse.RedirectURL,
QRcode: orderResponse.QRCode,
}
}
func MapOrderToExecuteCheckinResponse(order *entity.Order) response.ExecuteCheckinResponse {
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.ExecuteCheckinResponse{
ID: order.ID,
PartnerID: order.PartnerID,
Status: order.Status,
Amount: order.Amount,
PaymentType: order.PaymentType,
CreatedAt: order.CreatedAt,
OrderItems: orderItems,
}
}
func (h *Handler) toHistoryOrderResponse(resp *entity.HistoryOrder) response.HistoryOrder {
return response.HistoryOrder{
ID: resp.ID,
Employee: resp.Employee,
Site: resp.Site,
Timestamp: resp.Timestamp.Format("2006-01-02 15:04:05"),
BookingTime: resp.BookingTime.Format("2006-01-02 15:04:05"),
Tickets: resp.Tickets,
PaymentType: resp.PaymentType,
Status: resp.Status,
Amount: resp.Amount,
VisitDate: resp.VisitDate.Format("2006-01-02"),
TicketStatus: resp.TicketStatus,
Source: resp.Source,
}
}
func (h *Handler) SumAmount(c *gin.Context) {
var req request.OrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
order, err := h.service.SumAmount(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.OrderAmount{
Amount: order.Amount,
},
})
}
func (h *Handler) GetAllHistoryOrders(c *gin.Context) {
var req request.OrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
orders, total, err := h.service.GetAllHistoryOrders(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toHistoryOrderList(orders, int64(total), req),
})
}
func (h *Handler) CountSoldOfTicket(c *gin.Context) {
var req request.OrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
res, err := h.service.CountSoldOfTicket(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: response.TicketSold{
Count: res.Count,
},
})
}
func (h *Handler) GetDailySalesTicket(c *gin.Context) {
var req request.OrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
resp, err := h.service.GetDailySales(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toDailySales(resp),
})
}
func (h *Handler) GetPaymentDistributionChart(c *gin.Context) {
var req request.OrderParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
ctx := request.GetMyContext(c)
resp, err := h.service.GetPaymentDistribution(ctx, req.ToOrderEntity(ctx))
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toPaymentDistributionChart(resp),
})
}
func (h *Handler) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.OrderParam) response.HistoryOrderList {
var orders []response.HistoryOrder
for _, b := range resp {
orders = append(orders, h.toHistoryOrderResponse(b))
}
return response.HistoryOrderList{
Orders: orders,
Total: total,
Limit: req.Limit,
Offset: req.Offset,
}
}
func (h *Handler) toDailySales(resp []entity.ProductDailySales) []response.ProductDailySales {
var dailySales []response.ProductDailySales
for _, b := range resp {
dailySales = append(dailySales, response.ProductDailySales{
Day: b.Day,
SiteID: b.SiteID,
Total: b.Total,
SiteName: b.SiteName,
PaymentType: b.PaymentType,
})
}
return dailySales
}
func (h *Handler) toPaymentDistributionChart(resp []entity.PaymentTypeDistribution) []response.PaymentDistribution {
var dailySales []response.PaymentDistribution
for _, b := range resp {
dailySales = append(dailySales, response.PaymentDistribution{
PaymentType: b.PaymentType,
Count: b.Count,
})
}
return dailySales
}
func MapOrderToPrintDetailResponse(order *entity.OrderPrintDetail, casherName string) response.PrintDetailResponse {
orderItems := make([]response.CreateOrderItemResponse, len(order.OrderItems))
for i, item := range order.OrderItems {
orderItems[i] = response.CreateOrderItemResponse{
ID: item.ID,
ItemID: item.ItemID,
Quantity: item.Quantity,
Price: item.Price,
Name: item.Product.Name,
}
}
return response.PrintDetailResponse{
ID: order.ID,
OrderID: order.OrderID,
Total: order.Total,
Fee: order.Fee,
PaymentType: order.GetPaymanetType(),
Source: order.Source,
VisitDateAt: order.VisitDate.Format("2006-01-02"),
VisitTime: time.Now().Format("15:04:05"),
OrderItems: orderItems,
CasheerName: casherName,
PartnerName: order.SiteName,
Logo: order.Logo,
}
}
+11 -2
View File
@@ -55,7 +55,6 @@ func (h *Handler) Create(c *gin.Context) {
}
req.PartnerID = *ctx.GetPartnerID()
req.SiteID = *ctx.GetSiteID()
res, err := h.service.Create(ctx, req.ToEntity())
@@ -140,7 +139,9 @@ func (h *Handler) GetAll(c *gin.Context) {
return
}
products, total, err := h.service.GetAll(c.Request.Context(), req.ToEntity())
ctx := request.GetMyContext(c)
products, total, err := h.service.GetAll(ctx, req.ToEntity(*ctx.GetPartnerID()))
if err != nil {
response.ErrorWrapper(c, err)
return
@@ -266,6 +267,13 @@ func (h *Handler) GetByID(c *gin.Context) {
}
func (h *Handler) toProductResponse(resp *entity.Product) response.Product {
category := response.Category{}
if resp.Category != nil {
category.ID = resp.Category.ID
category.Name = resp.Category.Name
}
return response.Product{
ID: resp.ID,
Name: resp.Name,
@@ -274,6 +282,7 @@ func (h *Handler) toProductResponse(resp *entity.Product) response.Product {
Status: resp.Status,
Description: resp.Description,
Image: resp.Image,
Category: category,
}
}
-232
View File
@@ -1,232 +0,0 @@
package studio
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"
"encoding/json"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
)
type StudioHandler struct {
service services.Studio
}
func (h *StudioHandler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
route := group.Group("/studio")
route.POST("/", jwt, h.Create)
route.PUT("/:id", jwt, h.Update)
route.GET("/:id", jwt, h.GetByID)
route.GET("/search", jwt, h.Search)
}
func NewStudioHandler(service services.Studio) *StudioHandler {
return &StudioHandler{
service: service,
}
}
// Create handles the creation of a new studio.
// @Summary Create a new studio
// @Description Create a new studio based on the provided details.
// @Accept json
// @Produce json
// @Param Authorization header string true "JWT token"
// @Param req body request.Studio true "New studio details"
// @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio created successfully"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized"
// @Router /api/v1/studio [post]
// @Tags Studio APIs
func (h *StudioHandler) Create(c *gin.Context) {
ctx := request.GetMyContext(c)
var req request.Studio
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
}
res, err := h.service.Create(ctx, req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toStudioResponse(res),
})
}
// Update handles the update of an existing studio.
// @Summary Update an existing studio
// @Description Update the details of an existing studio based on the provided ID.
// @Accept json
// @Produce json
// @Param Authorization header string true "JWT token"
// @Param id path int64 true "Studio ID to update"
// @Param req body request.Studio true "Updated studio details"
// @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio updated successfully"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized"
// @Router /api/v1/studio/{id} [put]
// @Tags Studio APIs
func (h *StudioHandler) Update(c *gin.Context) {
ctx := request.GetMyContext(c)
id := c.Param("id")
studioID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
var req request.Studio
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
}
updatedStudio, err := h.service.Update(ctx, studioID, req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toStudioResponse(updatedStudio),
})
}
// Search retrieves a list of studios based on search criteria.
// @Summary Search for studios
// @Description Search for studios based on query parameters.
// @Accept json
// @Produce json
// @Param Authorization header string true "JWT token"
// @Param Name query string false "Studio name for search"
// @Param Status query string false "Studio status for search"
// @Param Limit query int false "Number of items to retrieve (default 10)"
// @Param Offset query int false "Offset for pagination (default 0)"
// @Success 200 {object} response.BaseResponse{data=response.StudioList} "List of studios"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized"
// @Router /api/v1/studio/search [get]
// @Tags Studio APIs
func (h *StudioHandler) Search(c *gin.Context) {
var req request.StudioParam
if err := c.ShouldBindQuery(&req); err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
studios, total, err := h.service.Search(c.Request.Context(), req.ToEntity())
if err != nil {
response.ErrorWrapper(c, err)
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toStudioResponseList(studios, int64(total), req),
})
}
// GetByID retrieves details of a specific studio by ID.
// @Summary Get details of a studio by ID
// @Description Get details of a studio based on the provided ID.
// @Accept json
// @Produce json
// @Param Authorization header string true "JWT token"
// @Param id path int64 true "Studio ID to retrieve"
// @Success 200 {object} response.BaseResponse{data=response.Studio} "Studio details"
// @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request"
// @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized"
// @Router /api/v1/studio/{id} [get]
// @Tags Studio APIs
func (h *StudioHandler) GetByID(c *gin.Context) {
id := c.Param("id")
studioID, err := strconv.ParseInt(id, 10, 64)
if err != nil {
response.ErrorWrapper(c, errors.ErrorBadRequest)
return
}
res, err := h.service.GetByID(c.Request.Context(), studioID)
if err != nil {
c.JSON(http.StatusInternalServerError, response.BaseResponse{
Success: false,
Status: http.StatusInternalServerError,
Message: err.Error(),
Data: nil,
})
return
}
c.JSON(http.StatusOK, response.BaseResponse{
Success: true,
Status: http.StatusOK,
Data: h.toStudioResponse(res),
})
}
func (h *StudioHandler) toStudioResponse(resp *entity.Studio) response.Studio {
metadata := make(map[string]interface{})
if err := json.Unmarshal(resp.Metadata, &metadata); err != nil {
//TODO taufanvps
// Handle the error if the metadata cannot be unmarshaled.
}
return response.Studio{
ID: &resp.ID,
BranchId: &resp.BranchId,
Name: resp.Name,
Status: string(resp.Status),
Price: resp.Price,
Metadata: metadata,
CreatedAt: resp.CreatedAt.Format(time.RFC3339),
UpdatedAt: resp.CreatedAt.Format(time.RFC3339),
}
}
func (h *StudioHandler) toStudioResponseList(resp []*entity.Studio, total int64, req request.StudioParam) response.StudioList {
var studios []response.Studio
for _, b := range resp {
studios = append(studios, h.toStudioResponse(b))
}
return response.StudioList{
Studios: studios,
Total: total,
Limit: req.Limit,
Offset: req.Offset,
}
}
+18
View File
@@ -0,0 +1,18 @@
package request
import "enaklo-pos-be/internal/entity"
type OpenCashierSessionRequest struct {
OpeningAmount float64 `json:"opening_amount" validate:"required,gt=0"`
}
type CloseCashierSessionRequest struct {
ClosingAmount float64 `json:"closing_amount" validate:"required"`
}
func (o *OpenCashierSessionRequest) ToEntity(cashierID int64) *entity.CashierSession {
return &entity.CashierSession{
CashierID: cashierID,
OpeningAmount: o.OpeningAmount,
}
}
+14
View File
@@ -0,0 +1,14 @@
package request
import "enaklo-pos-be/internal/entity"
type CategoryRequest struct {
Name string `json:"name" binding:"required"`
}
func (r *CategoryRequest) ToEntity(partnerID int64) *entity.Category {
return &entity.Category{
PartnerID: partnerID,
Name: r.Name,
}
}
+19 -15
View File
@@ -6,24 +6,26 @@ import (
)
type ProductParam struct {
Search string `form:"search" json:"search" example:"Nasi Goreng"`
Name string `form:"name" json:"name" example:"Nasi Goreng"`
Type product.ProductType `form:"type" json:"type" example:"FOOD/BEVERAGE"`
BranchID int64 `form:"branch_id" json:"branch_id" example:"1"`
Available product.ProductStock `form:"available" json:"available" example:"1" example:"AVAILABLE/UNAVAILABLE"`
Limit int `form:"limit" json:"limit" example:"10"`
Offset int `form:"offset" json:"offset" example:"0"`
Search string `form:"search" json:"search" example:"Nasi Goreng"`
Name string `form:"name" json:"name" example:"Nasi Goreng"`
Type product.ProductType `form:"type" json:"type" example:"FOOD/BEVERAGE"`
BranchID int64 `form:"branch_id" json:"branch_id" example:"1"`
Available product.ProductStock `form:"available" json:"available" example:"1" example:"AVAILABLE/UNAVAILABLE"`
Limit int `form:"limit" json:"limit" example:"10"`
Offset int `form:"offset" json:"offset" example:"0"`
CategoryID int64 `form:"category_id" json:"category_id" example:"1"`
}
func (p *ProductParam) ToEntity() entity.ProductSearch {
func (p *ProductParam) ToEntity(partnerID int64) entity.ProductSearch {
return entity.ProductSearch{
Search: p.Search,
Name: p.Name,
Type: p.Type,
BranchID: p.BranchID,
Available: p.Available,
Limit: p.Limit,
Offset: p.Offset,
Search: p.Search,
Name: p.Name,
Type: p.Type,
PartnerID: partnerID,
Available: p.Available,
Limit: p.Limit,
Offset: p.Offset,
CategoryID: p.CategoryID,
}
}
@@ -40,6 +42,7 @@ type Product struct {
Description string `json:"description"`
Stock int64 `json:"stock"`
Image string `json:"image"`
CategoryID int64 `json:"category_id"`
}
func (e *Product) ToEntity() *entity.Product {
@@ -51,5 +54,6 @@ func (e *Product) ToEntity() *entity.Product {
Description: e.Description,
PartnerID: e.PartnerID,
Image: e.Image,
CategoryID: &e.CategoryID,
}
}
+62
View File
@@ -0,0 +1,62 @@
package response
import (
"enaklo-pos-be/internal/entity"
"time"
)
type CashierSessionResponse struct {
ID int64 `json:"id"`
CashierID int64 `json:"cashier_id"`
OpenedAt time.Time `json:"opened_at"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
OpeningAmount float64 `json:"opening_amount"`
ClosingAmount *float64 `json:"closing_amount,omitempty"`
Status string `json:"status"`
}
type PaymentSummaryResponse struct {
PaymentType string `json:"payment_type"`
PaymentProvider string `json:"payment_provider"`
TotalAmount float64 `json:"total_amount"`
}
type CashierSessionReportResponse struct {
SessionID int64 `json:"session_id"`
ExpectedAmount float64 `json:"expected_amount"`
ClosingAmount float64 `json:"closing_amount"`
Payments []PaymentSummaryResponse `json:"payments"`
}
func MapToCashierSessionResponse(e *entity.CashierSession) *CashierSessionResponse {
if e == nil {
return nil
}
return &CashierSessionResponse{
ID: e.ID,
CashierID: e.CashierID,
OpenedAt: e.OpenedAt,
ClosedAt: e.ClosedAt,
OpeningAmount: e.OpeningAmount,
ClosingAmount: e.ClosingAmount,
Status: e.Status,
}
}
func MapToCashierSessionReport(e *entity.CashierSessionReport) *CashierSessionReportResponse {
payments := make([]PaymentSummaryResponse, len(e.Payments))
for i, p := range e.Payments {
payments[i] = PaymentSummaryResponse{
PaymentType: p.PaymentType,
PaymentProvider: p.PaymentProvider,
TotalAmount: p.TotalAmount,
}
}
return &CashierSessionReportResponse{
SessionID: e.SessionID,
ExpectedAmount: e.ExpectedAmount,
ClosingAmount: e.ClosingAmount,
Payments: payments,
}
}
+29
View File
@@ -0,0 +1,29 @@
package response
import "enaklo-pos-be/internal/entity"
type CategoryResponse struct {
ID int64 `json:"id"`
Name string `json:"name"`
PartnerID int64 `json:"partner_id"`
}
func MapToCategoryResponse(cat *entity.Category) *CategoryResponse {
if cat == nil {
return nil
}
return &CategoryResponse{
ID: cat.ID,
Name: cat.Name,
PartnerID: cat.PartnerID,
}
}
func MapToCategoryListResponse(cats []*entity.Category) []*CategoryResponse {
result := make([]*CategoryResponse, len(cats))
for i, c := range cats {
result[i] = MapToCategoryResponse(c)
}
return result
}
+13 -7
View File
@@ -1,13 +1,19 @@
package response
type Product struct {
ID int64 `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Price float64 `json:"price"`
Status string `json:"status"`
Description string `json:"description"`
Image string `json:"image"`
ID int64 `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Price float64 `json:"price"`
Status string `json:"status"`
Description string `json:"description"`
Image string `json:"image"`
Category Category `json:"category"`
}
type Category struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
type ProductList struct {