mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
171 lines
4.6 KiB
Go
171 lines
4.6 KiB
Go
package eshop
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"fotbal-club/internal/config"
|
|
"fotbal-club/internal/models"
|
|
"fotbal-club/internal/services"
|
|
"fotbal-club/pkg/database"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ShippingController struct {
|
|
Config *config.Config
|
|
PacketaService *services.PacketaService
|
|
}
|
|
|
|
func NewShippingController(cfg *config.Config) *ShippingController {
|
|
return &ShippingController{
|
|
Config: cfg,
|
|
PacketaService: services.NewPacketaService(cfg),
|
|
}
|
|
}
|
|
|
|
// GetPacketaWidgetConfig returns the configuration for the Packeta widget
|
|
func (c *ShippingController) GetPacketaWidgetConfig(ctx *gin.Context) {
|
|
ctx.JSON(http.StatusOK, gin.H{
|
|
"api_key": c.Config.PacketaWidgetAPIKey,
|
|
"env": c.Config.PacketaEnv,
|
|
})
|
|
}
|
|
|
|
// DownloadLabel handles the download of a shipping label PDF
|
|
// GET /api/v1/eshop/shipping/labels/:packet_id
|
|
func (c *ShippingController) DownloadLabel(ctx *gin.Context) {
|
|
packetID := ctx.Param("packet_id")
|
|
if packetID == "" {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "Missing packet ID"})
|
|
return
|
|
}
|
|
|
|
// In MVP, we might not have label download implemented in service yet
|
|
// pdfData, err := c.PacketaService.GetPacketLabel(packetID)
|
|
// Placeholder
|
|
pdfData, err := c.PacketaService.GetPacketLabel(packetID)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to download label"})
|
|
return
|
|
}
|
|
|
|
ctx.Header("Content-Type", "application/pdf")
|
|
ctx.Header("Content-Disposition", fmt.Sprintf(`attachment; filename="label_%s.pdf"`, packetID))
|
|
ctx.Data(http.StatusOK, "application/pdf", pdfData)
|
|
}
|
|
|
|
// CreatePacket creates a shipment in Packeta system from an order
|
|
func (c *ShippingController) CreatePacket(ctx *gin.Context) {
|
|
id := ctx.Param("id")
|
|
|
|
// Use a new DB connection or pass it via struct if possible.
|
|
// For now, InitDB (cached instance)
|
|
db, _ := database.InitDB()
|
|
|
|
var order models.EshopOrder
|
|
if err := db.First(&order, id).Error; err != nil {
|
|
ctx.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
|
|
return
|
|
}
|
|
|
|
if order.ShippingMethod != "packeta" {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "Not a Packeta order"})
|
|
return
|
|
}
|
|
|
|
// Parse shipping address JSON to get point ID
|
|
// Format: {"id":"123", "name":"Z-Point..."}
|
|
var pointData struct {
|
|
ID interface{} `json:"id"`
|
|
}
|
|
if err := json.Unmarshal([]byte(order.ShippingAddressJSON), &pointData); err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse shipping address"})
|
|
return
|
|
}
|
|
|
|
addressID := fmt.Sprintf("%v", pointData.ID)
|
|
if addressID == "" {
|
|
ctx.JSON(http.StatusBadRequest, gin.H{"error": "Missing Packeta point ID"})
|
|
return
|
|
}
|
|
|
|
packetID, err := c.PacketaService.CreatePacket(&order, addressID)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Packeta API error: " + err.Error()})
|
|
return
|
|
}
|
|
|
|
// Create Label record
|
|
label := models.EshopShippingLabel{
|
|
OrderID: order.ID,
|
|
PacketaPacketID: packetID,
|
|
Carrier: "packeta",
|
|
Status: "created",
|
|
}
|
|
db.Create(&label)
|
|
|
|
// Update order status
|
|
order.Status = "ready_to_ship"
|
|
db.Save(&order)
|
|
|
|
ctx.JSON(http.StatusOK, gin.H{
|
|
"packet_id": packetID,
|
|
"status": "created",
|
|
})
|
|
}
|
|
|
|
// Background job
|
|
func (c *ShippingController) UpdatePacketStatuses(db *gorm.DB) {
|
|
var labels []models.EshopShippingLabel
|
|
// Check active shipments
|
|
if err := db.Where("status NOT IN ?", []string{"delivered", "cancelled", "returned"}).Find(&labels).Error; err != nil {
|
|
return
|
|
}
|
|
|
|
for _, label := range labels {
|
|
status, err := c.PacketaService.GetPacketStatus(label.PacketaPacketID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
if label.Status != status {
|
|
// Update label status
|
|
label.Status = status
|
|
if err := db.Save(&label).Error; err != nil {
|
|
continue
|
|
}
|
|
|
|
// Update order status based on shipping status
|
|
c.updateOrderStatusFromShipping(db, label.OrderID, status)
|
|
}
|
|
}
|
|
}
|
|
|
|
// updateOrderStatusFromShipping updates order status based on shipping status
|
|
func (c *ShippingController) updateOrderStatusFromShipping(db *gorm.DB, orderID uint, shippingStatus string) {
|
|
var newOrderStatus string
|
|
|
|
switch shippingStatus {
|
|
case "ready_to_ship", "collected":
|
|
newOrderStatus = "processing"
|
|
case "in_transit", "out_for_delivery":
|
|
newOrderStatus = "shipped"
|
|
case "delivered":
|
|
newOrderStatus = "completed"
|
|
case "cancelled", "returned":
|
|
newOrderStatus = shippingStatus
|
|
default:
|
|
return // No status change needed
|
|
}
|
|
|
|
if err := db.Model(&models.EshopOrder{}).
|
|
Where("id = ?", orderID).
|
|
Update("status", newOrderStatus).Error; err != nil {
|
|
// Log error but don't fail the entire process
|
|
return
|
|
}
|
|
}
|