mirror of
https://github.com/hanzoai/commerce.git
synced 2026-10-30 15:08:42 +00:00
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans, usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0. Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
150 lines
3.8 KiB
Go
150 lines
3.8 KiB
Go
package shipnotify
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/zap-proto/zip"
|
|
|
|
"github.com/hanzoai/commerce/datastore"
|
|
"github.com/hanzoai/commerce/email"
|
|
"github.com/hanzoai/commerce/log"
|
|
"github.com/hanzoai/commerce/middleware"
|
|
"github.com/hanzoai/commerce/models/order"
|
|
"github.com/hanzoai/commerce/models/payment"
|
|
"github.com/hanzoai/commerce/models/types/currency"
|
|
"github.com/hanzoai/commerce/models/types/fulfillment"
|
|
"github.com/hanzoai/commerce/models/user"
|
|
)
|
|
|
|
// <?xml version="1.0" encoding="utf-8"?>
|
|
// <ShipNotice>
|
|
// <OrderNumber>ABC123</OrderNumber>
|
|
// <CustomerCode>[email protected]</CustomerCode>
|
|
// <LabelCreateDate>12/8/2011 12:56 PM</LabelCreateDate>
|
|
// <ShipDate>12/8/2011</ShipDate>
|
|
// <Carrier>USPS</Carrier>
|
|
// <Service>Priority Mail</Service>
|
|
// <TrackingNumber>1Z909084330298430820</TrackingNumber>
|
|
// <ShippingCost>4.95</ShippingCost>
|
|
// <Recipient>
|
|
// <Name>The President</Name>
|
|
// <Company>US Govt</Company>
|
|
// <Address1>1600 Pennsylvania Ave</Address1>
|
|
// <Address2></Address2>
|
|
// <City>Washington</City>
|
|
// <State>DC</State>
|
|
// <PostalCode>20500</PostalCode>
|
|
// <Country>US</Country>
|
|
// </Recipient>
|
|
// <Items>
|
|
// <Item>
|
|
// <SKU>FD88821</SKU>
|
|
// <Name>My Product Name</Name>
|
|
// <Quantity>2</Quantity>
|
|
// </Item>
|
|
// </Items>
|
|
// </ShipNotice>
|
|
|
|
func parseDate(s string) time.Time {
|
|
date, err := time.Parse("01/02/2006", s)
|
|
if err != nil {
|
|
log.Panic("Unable to parse date: %v", err)
|
|
}
|
|
return date
|
|
}
|
|
|
|
func parseTime(s string) time.Time {
|
|
date, err := time.Parse("01/02/2006 15:04", s)
|
|
if err != nil {
|
|
log.Panic("Unable to parse time: %v", err)
|
|
}
|
|
return date
|
|
}
|
|
|
|
type Request struct {
|
|
OrderNumber string
|
|
CustomerCode string
|
|
LabelCreateDate string
|
|
ShipDate string
|
|
Carrier string
|
|
Service string
|
|
TrackingNumber string
|
|
ShippingCost string
|
|
|
|
Recipient struct {
|
|
Name string
|
|
Company string
|
|
Address1 string
|
|
Address2 string
|
|
City string
|
|
State string
|
|
PostalCode string
|
|
Country string
|
|
}
|
|
|
|
Items []struct {
|
|
SKU string
|
|
Name string
|
|
Quantity string
|
|
}
|
|
}
|
|
|
|
func ShipNotify(c *zip.Ctx) error {
|
|
// Only support export action
|
|
action := c.Query("action")
|
|
if action != "shipnotify" {
|
|
log.Panic("Invalid action %s, only understand 'shipnotify'", action, c)
|
|
}
|
|
|
|
orderNumber := c.Query("order_number")
|
|
id, err := strconv.Atoi(orderNumber)
|
|
if err != nil {
|
|
log.Panic("Unable to convert order_number '%s' to int: %v", orderNumber, err, c)
|
|
}
|
|
|
|
org := middleware.GetOrganization(c)
|
|
db := datastore.New(org.Namespaced(c.Context()))
|
|
|
|
ord := order.New(db)
|
|
ok, err := ord.Query().Filter("Number=", id).Get()
|
|
if !ok || err != nil {
|
|
log.Warn("Unable to find order '%s': %v", id, err, c)
|
|
return c.String(200, "ok\n")
|
|
}
|
|
|
|
b := c.Body()
|
|
|
|
req := Request{}
|
|
if err := xml.Unmarshal(b, &req); err != nil {
|
|
log.Panic("Unable to unmarshal XML: %v", err, c)
|
|
}
|
|
|
|
if ord.Fulfillment.Trackings[0].Number != req.TrackingNumber {
|
|
ord.Fulfillment.Status = fulfillment.Tracked
|
|
ord.Fulfillment.Trackings[0].Number = req.TrackingNumber
|
|
ord.Fulfillment.Trackings[0].LabelCreatedAt = parseTime(req.LabelCreateDate)
|
|
ord.Fulfillment.Service = req.Service
|
|
ord.Fulfillment.Carrier = req.Carrier
|
|
shipCost, err := currency.USD.Parse(req.ShippingCost)
|
|
if err != nil {
|
|
return fmt.Errorf("shipstation shipping cost: %w", err)
|
|
}
|
|
ord.Fulfillment.Pricing = shipCost
|
|
|
|
usr := user.New(db)
|
|
usr.MustGetById(ord.UserId)
|
|
|
|
pay := payment.New(db)
|
|
pay.MustGetById(ord.PaymentIds[0])
|
|
|
|
email.SendOrderShipped(db.Context, org, ord, usr, pay)
|
|
}
|
|
|
|
ord.MustPut()
|
|
|
|
return c.String(200, "ok\n")
|
|
}
|