Merge pull request 'history-order-list' (#1) from history-order-list into main
Reviewed-on: https://git.altru.id/Furtuna/furtuna-backend/pulls/1
This commit is contained in:
commit
fade68e4bf
2
go.sum
2
go.sum
@ -84,8 +84,6 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/getbrevo/brevo-go v1.0.0 h1:E/pRCsQeExvZeTCJU5vy+xHWcLaL5axWQ9QkxjlFke4=
|
||||
github.com/getbrevo/brevo-go v1.0.0/go.mod h1:2TBMEnaDqq/oiAXUYtn6eykiEdHcEoS7tc63+YoFibw=
|
||||
github.com/getbrevo/brevo-go v1.1.1 h1:6/SXEQ7ZfUjetPnJ4EncfLSUgXjQv4qUj1EQgLXnDto=
|
||||
github.com/getbrevo/brevo-go v1.1.1/go.mod h1:ExhytIoPxt/cOBl6ZEMeEZNLUKrWEYA5U3hM/8WP2bg=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
|
||||
@ -13,6 +13,7 @@ type Context interface {
|
||||
|
||||
RequestedBy() int64
|
||||
IsSuperAdmin() bool
|
||||
IsAdmin() bool
|
||||
IsCasheer() bool
|
||||
GetPartnerID() *int64
|
||||
GetSiteID() *int64
|
||||
@ -36,6 +37,10 @@ func (m *MyContextImpl) IsSuperAdmin() bool {
|
||||
return m.roleID == int(role.SuperAdmin)
|
||||
}
|
||||
|
||||
func (m *MyContextImpl) IsAdmin() bool {
|
||||
return m.roleID == int(role.SuperAdmin) || m.roleID == int(role.Admin)
|
||||
}
|
||||
|
||||
func (m *MyContextImpl) IsCasheer() bool {
|
||||
return m.roleID == int(role.Casheer)
|
||||
}
|
||||
|
||||
@ -81,3 +81,58 @@ type CallbackRequest struct {
|
||||
TransactionStatus string `json:"transaction_status"`
|
||||
TransactionID string `json:"transaction_id"`
|
||||
}
|
||||
|
||||
type HistoryOrder struct {
|
||||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||||
Employee string `gorm:"type:varchar;column:employee"`
|
||||
Site string `gorm:"type:varchar;column:site"`
|
||||
Timestamp time.Time `gorm:"autoCreateTime;column:timestamp"`
|
||||
BookingTime time.Time `gorm:"autoCreateTime;column:booking_time"`
|
||||
Tickets []string `gorm:"-"`
|
||||
RawTickets string `gorm:"type:text;column:tickets"`
|
||||
PaymentType string `gorm:"type:varchar;column:payment_type"`
|
||||
Status string `gorm:"type:varchar;column:status"`
|
||||
Amount float64 `gorm:"type:numeric;column:amount"`
|
||||
}
|
||||
|
||||
type HistoryOrderDB struct {
|
||||
HistoryOrder
|
||||
}
|
||||
|
||||
type HistoryOrderSearch struct {
|
||||
PartnerID *int64
|
||||
IsAdmin bool
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
|
||||
type HistoryOrderList []*HistoryOrderDB
|
||||
|
||||
func (b *HistoryOrder) ToHistoryOrderDB() *HistoryOrderDB {
|
||||
return &HistoryOrderDB{
|
||||
HistoryOrder: *b,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *HistoryOrderDB) ToHistoryOrder() *HistoryOrder {
|
||||
return &HistoryOrder{
|
||||
ID: e.ID,
|
||||
Employee: e.Employee,
|
||||
Site: e.Site,
|
||||
Timestamp: e.Timestamp,
|
||||
BookingTime: e.BookingTime,
|
||||
Tickets: e.Tickets,
|
||||
RawTickets: e.RawTickets,
|
||||
PaymentType: e.PaymentType,
|
||||
Status: e.Status,
|
||||
Amount: e.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *HistoryOrderList) ToHistoryOrderList() []*HistoryOrder {
|
||||
var HistoryOrders []*HistoryOrder
|
||||
for _, historyOrder := range *b {
|
||||
HistoryOrders = append(HistoryOrders, historyOrder.ToHistoryOrder())
|
||||
}
|
||||
return HistoryOrders
|
||||
}
|
||||
|
||||
@ -6,9 +6,11 @@ import (
|
||||
"furtuna-be/internal/handlers/request"
|
||||
"furtuna-be/internal/handlers/response"
|
||||
"furtuna-be/internal/services"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
@ -20,6 +22,7 @@ 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.GetAllHistoryOrders)
|
||||
}
|
||||
|
||||
func NewHandler(service services.Order) *Handler {
|
||||
@ -151,3 +154,52 @@ func MapOrderToExecuteOrderResponse(orderResponse *entity.ExecuteOrderResponse)
|
||||
RedirectURL: orderResponse.RedirectURL,
|
||||
}
|
||||
}
|
||||
|
||||
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.Status,
|
||||
Amount: resp.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) GetAllHistoryOrders(c *gin.Context) {
|
||||
var req request.HistoryOrderParam
|
||||
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.ToEntity(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) toHistoryOrderList(resp []*entity.HistoryOrder, total int64, req request.HistoryOrderParam) 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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"furtuna-be/internal/common/mycontext"
|
||||
"furtuna-be/internal/constants/transaction"
|
||||
"furtuna-be/internal/entity"
|
||||
)
|
||||
@ -11,6 +12,20 @@ type Order struct {
|
||||
OrderItems []OrderItem `json:"order_items" validate:"required"`
|
||||
}
|
||||
|
||||
type HistoryOrderParam struct {
|
||||
Limit int `form:"limit" json:"limit" example:"10"`
|
||||
Offset int `form:"offset" json:"offset" example:"0"`
|
||||
}
|
||||
|
||||
func (o *HistoryOrderParam) ToEntity(ctx mycontext.Context) entity.HistoryOrderSearch {
|
||||
return entity.HistoryOrderSearch{
|
||||
PartnerID: ctx.GetPartnerID(),
|
||||
IsAdmin: ctx.IsAdmin(),
|
||||
Limit: o.Limit,
|
||||
Offset: o.Offset,
|
||||
}
|
||||
}
|
||||
|
||||
type OrderItem struct {
|
||||
ProductID int64 `json:"product_id" validate:"required"`
|
||||
Quantity int64 `json:"quantity" validate:"required"`
|
||||
|
||||
@ -21,6 +21,18 @@ type Order struct {
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
type HistoryOrder struct {
|
||||
ID int64 `json:"id"`
|
||||
Employee string `json:"employee"`
|
||||
Site string `json:"site"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
BookingTime string `json:"booking_time"`
|
||||
Tickets []string `json:"tickets"`
|
||||
PaymentType string `json:"payment_type"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount"`
|
||||
}
|
||||
|
||||
type OrderItem struct {
|
||||
OrderItemID int64 `json:"order_item_id" `
|
||||
ItemID int64 `json:"item_id" `
|
||||
@ -39,6 +51,13 @@ type OrderList struct {
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
type HistoryOrderList struct {
|
||||
Orders []HistoryOrder `json:"history_orders"`
|
||||
Total int64 `json:"total"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
type OrderMonthlyRevenue struct {
|
||||
TotalRevenue float64 `json:"total_revenue"`
|
||||
TotalTransaction int64 `json:"total_transaction"`
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/entity"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -80,3 +82,49 @@ func (r *OrderRepository) Update(ctx context.Context, order *entity.Order) (*ent
|
||||
}
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetAllHystoryOrders(ctx context.Context, req entity.HistoryOrderSearch) (entity.HistoryOrderList, int, error) {
|
||||
var orders []*entity.HistoryOrderDB
|
||||
var total int64
|
||||
|
||||
query := b.db.Table("orders").
|
||||
Select("orders.id as id, users.name as employee, sites.name as site, orders.created_at as timestamp, orders.created_at as booking_time, STRING_AGG(ticket_summary.name || ' x' || ticket_summary.total_qty, ', ') AS tickets, orders.payment_type as payment_type, orders.status as status, orders.amount as amount").
|
||||
Joins("left join (SELECT items.order_id, products.name, SUM(items.qty) AS total_qty FROM order_items items LEFT JOIN products ON items.item_id = products.id GROUP BY items.order_id, products.name) AS ticket_summary ON orders.id = ticket_summary.order_id").
|
||||
Joins("left join users on orders.created_by = users.id").
|
||||
Joins("left join partners on orders.partner_id = partners.id").
|
||||
Joins("left join sites on partners.id = sites.partner_id")
|
||||
|
||||
if !req.IsAdmin {
|
||||
query = query.Where("orders.partner_id = ?", req.PartnerID)
|
||||
}
|
||||
|
||||
query = query.Group("orders.id, users.name, sites.name, orders.created_at, orders.payment_type, orders.status")
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when count history orders", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
page := (req.Offset - 1) * req.Limit
|
||||
|
||||
if req.Offset > 0 {
|
||||
query = query.Offset(page)
|
||||
}
|
||||
|
||||
if req.Limit > 0 {
|
||||
query = query.Limit(req.Limit)
|
||||
}
|
||||
|
||||
if err := query.Scan(&orders).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
for i, order := range orders {
|
||||
if order.RawTickets != "" {
|
||||
orders[i].Tickets = strings.Split(order.RawTickets, ", ")
|
||||
}
|
||||
}
|
||||
|
||||
return orders, int(total), nil
|
||||
}
|
||||
|
||||
@ -130,6 +130,7 @@ type Order interface {
|
||||
FindByID(ctx context.Context, id int64) (*entity.Order, error)
|
||||
Update(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
||||
SetOrderStatus(ctx context.Context, db *gorm.DB, orderID int64, status string) error
|
||||
GetAllHystoryOrders(ctx context.Context, req entity.HistoryOrderSearch) (entity.HistoryOrderList, int, error)
|
||||
}
|
||||
|
||||
type OSSRepository interface {
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/common/mycontext"
|
||||
order2 "furtuna-be/internal/constants/order"
|
||||
"furtuna-be/internal/entity"
|
||||
"furtuna-be/internal/repository"
|
||||
@ -296,3 +297,15 @@ func (s *OrderService) updateWalletBalance(ctx context.Context, tx *gorm.DB, par
|
||||
_, err = s.wallet.Update(ctx, tx, wallet)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *OrderService) GetAllHistoryOrders(ctx mycontext.Context, req entity.HistoryOrderSearch) ([]*entity.HistoryOrder, int, error) {
|
||||
historyOrders, total, err := s.repo.GetAllHystoryOrders(ctx, req)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when get all history orders", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
data := historyOrders.ToHistoryOrderList()
|
||||
|
||||
return data, total, nil
|
||||
}
|
||||
|
||||
@ -8,9 +8,10 @@ import (
|
||||
"furtuna-be/internal/services/oss"
|
||||
"furtuna-be/internal/services/partner"
|
||||
"furtuna-be/internal/services/product"
|
||||
"furtuna-be/internal/services/sites"
|
||||
site "furtuna-be/internal/services/sites"
|
||||
"furtuna-be/internal/services/studio"
|
||||
"furtuna-be/internal/services/users"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"furtuna-be/config"
|
||||
@ -41,9 +42,8 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl)
|
||||
BranchSvc: branch.NewBranchService(repo.Branch),
|
||||
StudioSvc: studio.NewStudioService(repo.Studio),
|
||||
ProductSvc: product.NewProductService(repo.Product),
|
||||
OrderSvc: order.NewOrderService(repo.Order, repo.Product,
|
||||
repo.Crypto, repo.Midtrans, repo.Payment, repo.Trx, repo.Wallet),
|
||||
OSSSvc: oss.NewOSSService(repo.OSS),
|
||||
OrderSvc: order.NewOrderService(repo.Order, repo.Product, repo.Crypto, repo.Midtrans, repo.Payment, repo.Trx, repo.Wallet),
|
||||
OSSSvc: oss.NewOSSService(repo.OSS),
|
||||
PartnerSvc: partner.NewPartnerService(
|
||||
repo.Partner, users.NewUserService(repo.User, repo.Branch), repo.Trx, repo.Wallet),
|
||||
SiteSvc: site.NewSiteService(repo.Site),
|
||||
@ -101,6 +101,7 @@ type Order interface {
|
||||
CreateOrder(ctx context.Context, req *entity.OrderRequest) (*entity.OrderResponse, error)
|
||||
Execute(ctx context.Context, req *entity.OrderExecuteRequest) (*entity.ExecuteOrderResponse, error)
|
||||
ProcessCallback(ctx context.Context, req *entity.CallbackRequest) error
|
||||
GetAllHistoryOrders(ctx mycontext.Context, req entity.HistoryOrderSearch) ([]*entity.HistoryOrder, int, error)
|
||||
}
|
||||
|
||||
type OSSService interface {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user