feat(onpoint): get inventories #17

Merged
sinhluu merged 8 commits from onpoint-stock-update into master 2024-05-08 07:26:17 +00:00
4 changed files with 112 additions and 12 deletions

View File

@ -21,13 +21,14 @@ const (
apiPathUpdateDelivery = "/v1/orders/update_delivery" apiPathUpdateDelivery = "/v1/orders/update_delivery"
apiPathCancelOrder = "/v1/orders/cancel" apiPathCancelOrder = "/v1/orders/cancel"
apiPathGetChannels = "/v1/channels" apiPathGetChannels = "/v1/channels"
apiPathGetInventories = "/v1/inventories"
headerXAPIKey = "x-api-key" headerXAPIKey = "x-api-key"
headerXTimestamp = "x-timestamp" headerXTimestamp = "x-timestamp"
headerXSignature = "x-signature" headerXSignature = "x-signature"
webhookEventUpdateOrderStatus = "UPDATE_ORDER_STATUS" webhookEventUpdateOrderStatus = "UPDATE_ORDER_STATUS"
webhookEventUpdateInventory = "update_inventory" webhookEventUpdateInventory = "UPDATE_INVENTORY"
) )
var ( var (

View File

@ -50,19 +50,24 @@ type CancelOrderRequest struct {
OrderNo string `json:"order_code"` OrderNo string `json:"order_code"`
} }
type ListInventoriesReq struct {
UpdatedFrom time.Time
UpdatedTo time.Time
SKUList []string
Size int
Page int
}
/** /**
* WEBHOOK ONPOINT * WEBHOOK ONPOINT
*/ */
// WebhookDataUpdateInventory ... // WebhookDataUpdateInventory ...
type WebhookDataUpdateInventory struct { type WebhookDataUpdateInventory struct {
Sku string `json:"sku"` Sku string `json:"sku"`
PartnerSku string `json:"partner_sku"` AvailableQuantity int `json:"available_quantity"`
WarehouseCode string `json:"warehouse_code"` PickupLocationCode string `json:"pickup_location_code"`
AvailableQuantity int `json:"available_quantity"` UpdatedAt time.Time `json:"updated_at"`
CommittedQuantity int `json:"committed_quantity"`
TotalQuantity int `json:"total_quantity"`
UpdatedAt string `json:"updated_at"`
} }
// WebhookDataUpdateOrderStatus ... // WebhookDataUpdateOrderStatus ...

View File

@ -1,5 +1,7 @@
package onpoint package onpoint
import "time"
// CreateOrderResponse ... // CreateOrderResponse ...
type CreateOrderResponse struct { type CreateOrderResponse struct {
OrderCode string `json:"order_code"` OrderCode string `json:"order_code"`
@ -34,3 +36,34 @@ type ChannelResponse struct {
Code string `json:"code"` Code string `json:"code"`
Name string `json:"name"` Name string `json:"name"`
} }
type ListInventoriesRes struct {
Code string `json:"code"`
Data struct {
Entries []InventoryEntry `json:"entries"`
Page int `json:"page"`
Size int `json:"size"`
TotalEntries int `json:"total_entries"`
TotalPages int `json:"total_pages"`
} `json:"data"`
}
type InventoryEntry struct {
AvailableQuantity int `json:"available_quantity"`
PickupLocation Pickup `json:"pickup_location"`
Product Product `json:"product"`
UpdatedAt time.Time `json:"updated_at"`
}
type Product struct {
Name string `json:"name"`
OriginalPrice int `json:"original_price"`
SellingPrice int `json:"selling_price"`
Sku string `json:"sku"`
Uom interface{} `json:"uom"`
}
type Pickup struct {
Code string `json:"code"`
Name string `json:"name"`
}

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -152,19 +153,77 @@ func (c *Client) CancelOrder(p CancelOrderRequest) (*CancelOrderResponse, error)
return &dataRes.Data, nil return &dataRes.Data, nil
} }
// GetInventories ...
func (c *Client) GetInventories(req ListInventoriesReq) (*ListInventoriesRes, error) {
url := c.getBaseURL() + apiPathGetInventories
q := map[string]string{}
if !req.UpdatedFrom.IsZero() {
q["updated_from"] = req.UpdatedFrom.Format(TimeLayout)
}
if !req.UpdatedTo.IsZero() {
q["updated_to"] = req.UpdatedTo.Format(TimeLayout)
}
if len(req.SKUList) > 0 {
q["sku_list"] = strings.Join(req.SKUList, ",")
}
if req.Page > 0 {
q["page"] = strconv.Itoa(req.Page)
}
if req.Size > 0 {
q["size"] = strconv.Itoa(req.Size)
}
natsPayload := model.CommunicationRequestHttp{
ResponseImmediately: true,
Payload: model.HttpRequest{
URL: url,
Method: http.MethodGet,
Query: q,
},
}
var (
r model.CommunicationHttpResponse
errRes Error
dataRes ListInventoriesRes
)
if err := c.requestHttpViaNats(natsPayload, &r); err != nil {
return nil, err
}
res := r.Response
if res == nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: empty_response")
}
if res.StatusCode >= http.StatusBadRequest {
if err := r.ParseResponseData(&errRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: parse_response_err: %v", err)
}
return nil, errRes
}
if err := r.ParseResponseData(&dataRes); err != nil {
return nil, fmt.Errorf("onpoint.Client.GetInventories: parse_response_data: %v", err)
}
return &dataRes, nil
}
func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp, res interface{}) error { func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp, res interface{}) error {
ec, err := c.natsClient.NewJSONEncodedConn() ec, err := c.natsClient.NewJSONEncodedConn()
if err != nil { if err != nil {
return fmt.Errorf("onpoint: request via nats %v", err) return fmt.Errorf("onpoint: request via nats %v", err)
} }
qs := "" u, err := url.ParseRequestURI(data.Payload.URL)
for k, v := range data.Payload.Query { if err != nil {
qs += k + "=" + v return fmt.Errorf("onpoint: request via nats %v", err)
} }
q := u.Query()
for k, v := range data.Payload.Query {
q.Set(k, v)
}
u.RawQuery = q.Encode()
now := time.Now().Unix() now := time.Now().Unix()
ts := strconv.FormatInt(now, 10) ts := strconv.FormatInt(now, 10)
arr := []string{ arr := []string{
qs, u.RawQuery,
data.Payload.Data, data.Payload.Data,
ts, ts,
} }
@ -177,6 +236,8 @@ func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp, res int
headerXTimestamp: ts, headerXTimestamp: ts,
httputil.HeaderKeyContentType: httputil.HeaderValueApplicationJSON, httputil.HeaderKeyContentType: httputil.HeaderValueApplicationJSON,
} }
data.Payload.Query = map[string]string{}
data.Payload.URL = u.String()
return ec.Request(subject.Communication.RequestHTTP, data, res) return ec.Request(subject.Communication.RequestHTTP, data, res)
} }