mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
159 lines
4.4 KiB
Go
159 lines
4.4 KiB
Go
package eshop
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
|
|
"fotbal-club/internal/config"
|
|
"fotbal-club/internal/models"
|
|
)
|
|
|
|
type PacketaService struct {
|
|
Config *config.Config
|
|
}
|
|
|
|
func NewPacketaService(cfg *config.Config) *PacketaService {
|
|
return &PacketaService{Config: cfg}
|
|
}
|
|
|
|
const packetaAPIURL = "https://www.zasilkovna.cz/api/rest"
|
|
|
|
// CreatePacket creates a new packet in Packeta system
|
|
func (s *PacketaService) CreatePacket(order *models.EshopOrder) (string, error) {
|
|
type PacketAttributes struct {
|
|
Number string `xml:"number"`
|
|
Name string `xml:"name"`
|
|
Surname string `xml:"surname"`
|
|
Email string `xml:"email"`
|
|
Phone string `xml:"phone"`
|
|
AddressID string `xml:"addressId"`
|
|
Value string `xml:"value"`
|
|
Currency string `xml:"currency"`
|
|
Weight string `xml:"weight"`
|
|
Eshop string `xml:"eshop"`
|
|
}
|
|
|
|
type CreatePacketRequest struct {
|
|
XMLName xml.Name `xml:"createPacket"`
|
|
ApiPassword string `xml:"apiPassword"`
|
|
PacketAttributes PacketAttributes `xml:"packetAttributes"`
|
|
}
|
|
|
|
// Extract shipping data
|
|
// order.ShippingDataJSON should contain the selected point ID (addressId)
|
|
// For now assuming we parse it or it is passed differently.
|
|
// In a real scenario, we would parse ShippingDataJSON to get the point ID.
|
|
addressID := "1483" // Fallback/Test ID if parsing fails. TODO: Implement proper parsing.
|
|
|
|
reqBody := CreatePacketRequest{
|
|
ApiPassword: s.Config.PacketaAPIPassword,
|
|
PacketAttributes: PacketAttributes{
|
|
Number: order.OrderNumber,
|
|
Name: order.FirstName,
|
|
Surname: order.LastName,
|
|
Email: order.Email,
|
|
Phone: "", // Phone is optional in our model but required for some carriers. TODO: Add phone to checkout.
|
|
AddressID: addressID,
|
|
Value: fmt.Sprintf("%.2f", float64(order.TotalAmountCents)/100.0),
|
|
Currency: order.Currency,
|
|
Weight: "1.0", // Default weight 1kg. TODO: Calculate from items.
|
|
Eshop: s.Config.PacketaEshopName,
|
|
},
|
|
}
|
|
|
|
respBytes, err := s.sendRequest(reqBody)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
type CreatePacketResponse struct {
|
|
PacketId string `xml:"packetId"`
|
|
Status string `xml:"status"`
|
|
Fault string `xml:"fault"`
|
|
}
|
|
|
|
var resp CreatePacketResponse
|
|
if err := xml.Unmarshal(respBytes, &resp); err != nil {
|
|
return "", fmt.Errorf("failed to parse response: %w", err)
|
|
}
|
|
|
|
if resp.Status != "ok" && resp.PacketId == "" {
|
|
return "", fmt.Errorf("packeta error: %s", resp.Fault)
|
|
}
|
|
|
|
return resp.PacketId, nil
|
|
}
|
|
|
|
// GetPacketLabel downloads the label PDF
|
|
func (s *PacketaService) GetPacketLabel(packetID string) ([]byte, error) {
|
|
type PacketLabelPdfRequest struct {
|
|
XMLName xml.Name `xml:"packetLabelPdf"`
|
|
ApiPassword string `xml:"apiPassword"`
|
|
PacketId string `xml:"packetId"`
|
|
Format string `xml:"format"`
|
|
Offset int `xml:"offset"`
|
|
}
|
|
|
|
reqBody := PacketLabelPdfRequest{
|
|
ApiPassword: s.Config.PacketaAPIPassword,
|
|
PacketId: packetID,
|
|
Format: "A6 on A4",
|
|
Offset: 0,
|
|
}
|
|
|
|
return s.sendRequest(reqBody)
|
|
}
|
|
|
|
// GetPacketStatus checks the status of a packet
|
|
func (s *PacketaService) GetPacketStatus(packetID string) (string, error) {
|
|
type PacketStatusRequest struct {
|
|
XMLName xml.Name `xml:"packetStatus"`
|
|
ApiPassword string `xml:"apiPassword"`
|
|
PacketId string `xml:"packetId"`
|
|
}
|
|
|
|
reqBody := PacketStatusRequest{
|
|
ApiPassword: s.Config.PacketaAPIPassword,
|
|
PacketId: packetID,
|
|
}
|
|
|
|
respBytes, err := s.sendRequest(reqBody)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Simplistic parsing for status text/code
|
|
// XML response structure varies slightly but usually contains <status>...</status>
|
|
// We might need a more robust struct.
|
|
return string(respBytes), nil
|
|
}
|
|
|
|
func (s *PacketaService) sendRequest(payload interface{}) ([]byte, error) {
|
|
xmlBytes, err := xml.Marshal(payload)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal request: %w", err)
|
|
}
|
|
|
|
client := &http.Client{Timeout: 10 * time.Second}
|
|
resp, err := client.Post(packetaAPIURL, "text/xml", bytes.NewReader(xmlBytes))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("request failed: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read response: %w", err)
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("API returned status %d: %s", resp.StatusCode, string(body))
|
|
}
|
|
|
|
return body, nil
|
|
}
|