package controllers import ( "fmt" "net/http" "situkang/dto" "situkang/services" "situkang/utils" "github.com/gin-gonic/gin" ) type OrderController interface { CreateOrder(ctx *gin.Context) ListOrders(ctx *gin.Context) GetOrderDetail(ctx *gin.Context) CancelOrder(ctx *gin.Context) GetTracking(ctx *gin.Context) GetTrackingLocation(ctx *gin.Context) ListPurchases(ctx *gin.Context) GetPurchaseDetail(ctx *gin.Context) ApprovePurchase(ctx *gin.Context) RejectPurchase(ctx *gin.Context) ClarifyPurchase(ctx *gin.Context) BulkApprovePurchases(ctx *gin.Context) ListChatMessages(ctx *gin.Context) SendChatMessage(ctx *gin.Context) MarkChatRead(ctx *gin.Context) ListChats(ctx *gin.Context) CreateRating(ctx *gin.Context) GetRating(ctx *gin.Context) GetInvoice(ctx *gin.Context) CreatePayment(ctx *gin.Context) DownloadInvoicePDF(ctx *gin.Context) SandboxCheckout(ctx *gin.Context) SandboxCallback(ctx *gin.Context) HandleMidtransWebhook(ctx *gin.Context) SyncMidtransPayment(ctx *gin.Context) } type orderController struct { orderService services.OrderService } func NewOrderController(orderService services.OrderService) OrderController { return &orderController{orderService: orderService} } func (oc *orderController) CreateOrder(ctx *gin.Context) { req := RequestJSON[dto.OrderCreateRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.CreateOrder(ctx, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusCreated, "Pesanan berhasil dibuat", data, nil) } func (oc *orderController) ListOrders(ctx *gin.Context) { data, err := oc.orderService.ListOrders(ctx) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, map[string]any{ "current_page": 1, "per_page": 10, "total": 0, "total_pages": 0, }) } func (oc *orderController) GetOrderDetail(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.GetOrderDetail(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) CancelOrder(ctx *gin.Context) { orderID := ctx.Param("order_id") req := RequestJSON[dto.OrderCancelRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.CancelOrder(ctx, orderID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Pesanan berhasil dibatalkan", data, nil) } func (oc *orderController) GetTracking(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.GetTracking(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) GetTrackingLocation(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.GetTrackingLocation(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) ListPurchases(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.ListPurchases(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, map[string]any{ "current_page": 1, "per_page": 20, "total": 0, "total_pages": 0, }) } func (oc *orderController) GetPurchaseDetail(ctx *gin.Context) { orderID := ctx.Param("order_id") purchaseID := ctx.Param("purchase_id") data, err := oc.orderService.GetPurchaseDetail(ctx, orderID, purchaseID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) ApprovePurchase(ctx *gin.Context) { orderID := ctx.Param("order_id") purchaseID := ctx.Param("purchase_id") req := RequestJSON[dto.PurchaseApproveRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.ApprovePurchase(ctx, orderID, purchaseID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Pembelian berhasil disetujui", data, nil) } func (oc *orderController) RejectPurchase(ctx *gin.Context) { orderID := ctx.Param("order_id") purchaseID := ctx.Param("purchase_id") req := RequestJSON[dto.PurchaseRejectRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.RejectPurchase(ctx, orderID, purchaseID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Pembelian ditolak", data, nil) } func (oc *orderController) ClarifyPurchase(ctx *gin.Context) { orderID := ctx.Param("order_id") purchaseID := ctx.Param("purchase_id") req := RequestJSON[dto.PurchaseClarifyRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.ClarifyPurchase(ctx, orderID, purchaseID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Permintaan klarifikasi berhasil dikirim", data, nil) } func (oc *orderController) BulkApprovePurchases(ctx *gin.Context) { orderID := ctx.Param("order_id") req := RequestJSON[dto.PurchaseBulkApproveRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.BulkApprovePurchases(ctx, orderID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Pembelian berhasil disetujui", data, nil) } func (oc *orderController) ListChatMessages(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.ListChatMessages(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) SendChatMessage(ctx *gin.Context) { orderID := ctx.Param("order_id") req := RequestJSON[dto.ChatSendRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.SendChatMessage(ctx, orderID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusCreated, "", data, nil) } func (oc *orderController) MarkChatRead(ctx *gin.Context) { orderID := ctx.Param("order_id") err := oc.orderService.MarkChatRead(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Semua pesan ditandai sudah dibaca", gin.H{}, nil) } func (oc *orderController) ListChats(ctx *gin.Context) { data, err := oc.orderService.ListChats(ctx) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, map[string]any{ "current_page": 1, "per_page": 20, "total": 0, "total_pages": 0, }) } func (oc *orderController) CreateRating(ctx *gin.Context) { orderID := ctx.Param("order_id") req := RequestJSON[dto.RatingCreateRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.CreateRating(ctx, orderID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusCreated, "Rating berhasil dikirim", data, nil) } func (oc *orderController) GetRating(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.GetRating(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) GetInvoice(ctx *gin.Context) { orderID := ctx.Param("order_id") data, err := oc.orderService.GetInvoice(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "", data, nil) } func (oc *orderController) CreatePayment(ctx *gin.Context) { orderID := ctx.Param("order_id") req := RequestJSON[dto.PaymentCreateRequest](ctx) if ctx.IsAborted() { return } data, err := oc.orderService.CreatePayment(ctx, orderID, req) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } utils.JSONSuccess(ctx, http.StatusOK, "Pembayaran berhasil dikonfirmasi", data, nil) } func (oc *orderController) DownloadInvoicePDF(ctx *gin.Context) { orderID := ctx.Param("order_id") content, err := oc.orderService.DownloadInvoicePDF(ctx, orderID) if err != nil { utils.ResponseFAILED(ctx, nil, err) return } ctx.Header("Content-Type", "application/pdf") ctx.Header("Content-Disposition", "attachment; filename=\"invoice.pdf\"") ctx.Data(http.StatusOK, "application/pdf", content) } func (oc *orderController) SandboxCheckout(ctx *gin.Context) { paymentID := ctx.Query("payment_id") if paymentID == "" { ctx.Data(http.StatusBadRequest, "text/html; charset=utf-8", []byte("
Missing payment_id parameter
")) return } details, err := oc.orderService.GetPaymentDetails(ctx, paymentID) if err != nil { ctx.Data(http.StatusNotFound, "text/html; charset=utf-8", []byte(fmt.Sprintf("%s
", err.Error()))) return } data := details.(map[string]any) amountFormatted := fmt.Sprintf("Rp %s", formatRupiah(data["amount"].(int))) html := fmt.Sprintf(`