mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 03:02:56 +00:00
hot fix #1
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user