Compare commits
44 Commits
Author | SHA1 | Date |
---|---|---|
Sinh | 64a2b6ee34 | |
Sinh | c19ab6b61e | |
Sinh | 07c8a4b7d0 | |
Sinh | 4b48142491 | |
Sinh | 570cf7b8f1 | |
Sinh | 308825f9c2 | |
Sinh | d2cf1a4dfd | |
Sinh | 79b19999f0 | |
Sinh | 2094a7b249 | |
Sinh | 0ea412e725 | |
Sinh | 8fe213156a | |
Sinh | ea7d9768d0 | |
Sinh | 2bf7ef6e8a | |
Sinh | 5466a2881c | |
Sinh | 76eeabdf7f | |
Sinh | b897f0b5c8 | |
Sinh | 82145021a1 | |
Sinh | 4f5b0f3f9a | |
Sinh | d0852f5d3a | |
Sinh | b9f59140a7 | |
Sinh | fef08db999 | |
Sinh | c2bfb0372c | |
Sinh | d272537cf4 | |
Sinh | 7c308c725c | |
Sinh | 8788f7e89b | |
Sinh | 46cccf22e2 | |
Sinh | 4f20218bcd | |
Sinh | f72dfcf95e | |
Sinh | 12549c1636 | |
Sinh | 5bf2e81ea9 | |
Sinh | 16ea108595 | |
sinhluu | e7efe49016 | |
sinhluu | 93aa6dd20f | |
Sinh | 0f678ff28a | |
Sinh | 61d7b5850d | |
Sinh | 4de10ff715 | |
Sinh | 328662cc95 | |
Sinh | d60dfd7673 | |
trunglt251292 | 5aebf6a070 | |
trunglt251292 | 38b82067c7 | |
Sinh | d33f3d7063 | |
Sinh | 8c519bbab7 | |
Sinh | 09f5647319 | |
Sinh | 4ddea224a1 |
2
go.mod
2
go.mod
|
@ -4,7 +4,7 @@ go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb
|
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb
|
||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393
|
git.selly.red/Selly-Modules/natsio v1.0.3-0.20240620022429-b891bfc9c52d
|
||||||
github.com/go-resty/resty/v2 v2.7.0
|
github.com/go-resty/resty/v2 v2.7.0
|
||||||
github.com/nats-io/nats.go v1.17.0
|
github.com/nats-io/nats.go v1.17.0
|
||||||
github.com/thoas/go-funk v0.9.2
|
github.com/thoas/go-funk v0.9.2
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,7 +1,7 @@
|
||||||
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb h1:AmcYd88IcdSkH+NEvKyJLT7psidSkjJQT/nAg/KuzFk=
|
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb h1:AmcYd88IcdSkH+NEvKyJLT7psidSkjJQT/nAg/KuzFk=
|
||||||
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb/go.mod h1:Q1//Z6HRmfa7VyjH2J6YyT0YV2jT8+K6SIgwnYuS4II=
|
git.selly.red/Selly-Modules/logger v0.0.2-0.20221010053254-567df039afdb/go.mod h1:Q1//Z6HRmfa7VyjH2J6YyT0YV2jT8+K6SIgwnYuS4II=
|
||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393 h1:43kE03FW3NONfE6hXlghafS1d233dfc7grlFqd+15SA=
|
git.selly.red/Selly-Modules/natsio v1.0.3-0.20240620022429-b891bfc9c52d h1:fSFFbzh+Xr7fjyn3R2smaEf/EPF78uZuHCq552OxJlU=
|
||||||
git.selly.red/Selly-Modules/natsio v1.0.3-0.20231020090841-5edec97ee393/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
|
git.selly.red/Selly-Modules/natsio v1.0.3-0.20240620022429-b891bfc9c52d/go.mod h1:KNODhfeBqxRmHHQHHU+p3JfH42t8s5aNxfgr6X8fr6g=
|
||||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (c *Client) GetOrder(orderCode string) (*GetOrderResponseDecoded, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error) {
|
func (c *Client) requestNats(subject string, data interface{}) (*nats.Msg, error) {
|
||||||
b := toBytes(data)
|
b := pjson.ToBytes(data)
|
||||||
return c.natsClient.Request(subject, b)
|
return c.natsClient.Request(subject, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,27 +3,10 @@ package globalcare
|
||||||
import (
|
import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/json"
|
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.selly.red/Selly-Modules/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// toBytes ...
|
|
||||||
func toBytes(data interface{}) []byte {
|
|
||||||
b, err := json.Marshal(data)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("pjson.toBytes", logger.LogData{"payload": data})
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// toJSONString ...
|
|
||||||
func toJSONString(data interface{}) string {
|
|
||||||
return string(toBytes(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GeneratePublicKeyFromBytes ...
|
// GeneratePublicKeyFromBytes ...
|
||||||
func generatePublicKeyFromBytes(b []byte) (*rsa.PublicKey, error) {
|
func generatePublicKeyFromBytes(b []byte) (*rsa.PublicKey, error) {
|
||||||
pubPem, _ := pem.Decode(b)
|
pubPem, _ := pem.Decode(b)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package onpoint
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -228,6 +229,8 @@ func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp, res int
|
||||||
ts,
|
ts,
|
||||||
}
|
}
|
||||||
s := strings.Join(arr, ".")
|
s := strings.Join(arr, ".")
|
||||||
|
log.Println("DEBUG: onpoint. secret_message:", s)
|
||||||
|
log.Println("DEBUG: onpoint. secret_key:", c.secretKey)
|
||||||
// sign data
|
// sign data
|
||||||
sign := hashSHA256AndUppercase(s, c.secretKey)
|
sign := hashSHA256AndUppercase(s, c.secretKey)
|
||||||
data.Payload.Header = map[string]string{
|
data.Payload.Header = map[string]string{
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
const (
|
||||||
|
TimeLayout = "2006-01-02 15:04:05"
|
||||||
|
|
||||||
|
apiPathCreateOutboundRequest = "/v1/api/external/vietful/outbound/requests"
|
||||||
|
apiPathGetOutboundRequest = "/v1/api/external/vietful/outbound/requests/%d"
|
||||||
|
apiPathCancelOutboundRequest = "/v1/api/external/vietful/outbound/requests/%d/cancel"
|
||||||
|
apiPathUpdateLogisticInfoOutboundRequest = "/v1/api/external/vietful/outbound/requests/%d/logistic-info"
|
||||||
|
apiPathAuth = "/v1/api/external/vietful/auth/access-token"
|
||||||
|
|
||||||
|
PriorityUrgent = 3
|
||||||
|
PriorityHigh = 2
|
||||||
|
PriorityNormal = 1
|
||||||
|
|
||||||
|
TPLCodeGHN = "GHN"
|
||||||
|
TPLCodeGHTK = "GHTK"
|
||||||
|
TPLCodeBest = "BEST"
|
||||||
|
TPLCodeSnappy = "SPY"
|
||||||
|
TPLCodeViettelPost = "VTP"
|
||||||
|
TPLCodeSellyExpress = "SE"
|
||||||
|
TPLCodeJTExpress = "JTE"
|
||||||
|
|
||||||
|
ShippingServiceCodeSTD = "STD"
|
||||||
|
ORTypeOrder = 1
|
||||||
|
ShippingTypeSelfShip = 1
|
||||||
|
PackTypeNormal = 1
|
||||||
|
BizTypeB2C = 1
|
||||||
|
ConditionTypeCodeNew = "NEW"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
baseURLAuthStaging = "https://api.shiip.vn"
|
||||||
|
baseURLStaging = "https://api.shiip.vn"
|
||||||
|
|
||||||
|
// TODO: add base URL
|
||||||
|
baseURLAuthProd = ""
|
||||||
|
baseURLProd = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrCodeExistPartnerCode = "exist_partner_code"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
baseURLENVMapping = map[ENV]string{
|
||||||
|
EnvProd: baseURLProd,
|
||||||
|
EnvStaging: baseURLStaging,
|
||||||
|
}
|
||||||
|
baseURLAuthENVMapping = map[ENV]string{
|
||||||
|
EnvProd: baseURLAuthProd,
|
||||||
|
EnvStaging: baseURLAuthStaging,
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,9 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
// ENV ...
|
||||||
|
type ENV string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EnvStaging ENV = "STAGING"
|
||||||
|
EnvProd ENV = "PROD"
|
||||||
|
)
|
|
@ -0,0 +1,22 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error ...
|
||||||
|
type Error struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"errorMessage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error ...
|
||||||
|
func (e Error) Error() string {
|
||||||
|
return fmt.Sprintf("tnc_err: code %s, messsage %s", e.Code, e.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrExistPartnerCode ...
|
||||||
|
func IsErrExistPartnerCode(err error) bool {
|
||||||
|
e, ok := err.(Error)
|
||||||
|
return ok && e.Code == ErrCodeExistPartnerCode
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
// Product ...
|
||||||
|
type Product struct {
|
||||||
|
PartnerSKU string `json:"partnerSKU"`
|
||||||
|
UnitCode string `json:"unitCode"`
|
||||||
|
ConditionTypeCode string `json:"conditionTypeCode"`
|
||||||
|
Quantity int64 `json:"quantity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Address ...
|
||||||
|
type Address struct {
|
||||||
|
AddressNo string `json:"addressNo"`
|
||||||
|
ProvinceCode string `json:"provinceCode,omitempty"`
|
||||||
|
DistrictCode string `json:"districtCode,omitempty"`
|
||||||
|
WardCode string `json:"wardCode,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// OutboundRequestPayload ...
|
||||||
|
type OutboundRequestPayload struct {
|
||||||
|
WarehouseCode string `json:"warehouseCode"`
|
||||||
|
ShippingServiceCode string `json:"shippingServiceCode"`
|
||||||
|
PartnerORCode string `json:"partnerORCode"`
|
||||||
|
PartnerRefId string `json:"partnerRefId"`
|
||||||
|
RefCode string `json:"refCode"`
|
||||||
|
CodAmount float64 `json:"codAmount"`
|
||||||
|
PriorityType int `json:"priorityType"`
|
||||||
|
CustomerName string `json:"customerName"`
|
||||||
|
CustomerPhoneNumber string `json:"customerPhoneNumber"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
ShippingType int `json:"shippingType"`
|
||||||
|
VehicleNumber string `json:"vehicleNumber"`
|
||||||
|
ContainerNumber string `json:"containerNumber"`
|
||||||
|
PackType int `json:"packType"`
|
||||||
|
PackingNote string `json:"packingNote"`
|
||||||
|
CustomLabel bool `json:"customLabel"`
|
||||||
|
BizType int `json:"bizType"`
|
||||||
|
Note string `json:"note"`
|
||||||
|
ShippingAddress Address `json:"shippingAddress"`
|
||||||
|
Products []Product `json:"products"`
|
||||||
|
PartnerCreationTime string `json:"partnerCreationTime"`
|
||||||
|
TPLCode string `json:"tplCode"`
|
||||||
|
TrackingCode string `json:"trackingCode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateORLogisticInfoPayload ...
|
||||||
|
type UpdateORLogisticInfoPayload struct {
|
||||||
|
OrID int `json:"orId"`
|
||||||
|
TrackingCode string `json:"trackingCode"`
|
||||||
|
ShippingLabels []Label `json:"shippingLabels"`
|
||||||
|
TPLCode string `json:"tplCode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Label struct {
|
||||||
|
Caption string `json:"caption"`
|
||||||
|
URI string `json:"uri"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthPayload struct {
|
||||||
|
ClientID string `json:"clientId"`
|
||||||
|
ClientSecret string `json:"clientSecret"`
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
// OutboundRequestRes ...
|
||||||
|
type OutboundRequestRes struct {
|
||||||
|
OrID int `json:"orId"`
|
||||||
|
OrCode string `json:"orCode"`
|
||||||
|
PartnerORCode string `json:"partnerORCode"`
|
||||||
|
Error *Error `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type authRes struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
ExpiresIn int `json:"expires_in"`
|
||||||
|
RefreshExpiresIn int `json:"refresh_expires_in"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
NotBeforePolicy int `json:"not-before-policy"`
|
||||||
|
SessionState string `json:"session_state"`
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webhook ...
|
||||||
|
type Webhook struct {
|
||||||
|
OrId int `json:"orId"`
|
||||||
|
PartnerORCode string `json:"partnerORCode"`
|
||||||
|
ErrorCode string `json:"errorCode"`
|
||||||
|
ErrorMessage string `json:"errorMessage"`
|
||||||
|
Event string `json:"event"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
Note string `json:"note"`
|
||||||
|
OrCode string `json:"orCode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// OutboundRequestInfo ...
|
||||||
|
type OutboundRequestInfo struct {
|
||||||
|
OrId int `json:"orId"`
|
||||||
|
OrCode string `json:"orCode"`
|
||||||
|
PartnerORCode string `json:"partnerORCode"`
|
||||||
|
OriginalPartnerOrCode string `json:"originalPartnerOrCode"`
|
||||||
|
PartnerRefId string `json:"partnerRefId"`
|
||||||
|
RefCode string `json:"refCode"`
|
||||||
|
WarehouseCode string `json:"warehouseCode"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Note string `json:"note"`
|
||||||
|
ShippingType int `json:"shippingType"`
|
||||||
|
PriorityType int `json:"priorityType"`
|
||||||
|
PackType int `json:"packType"`
|
||||||
|
BizType int `json:"bizType"`
|
||||||
|
CustomerName string `json:"customerName"`
|
||||||
|
CustomerPhoneNumber string `json:"customerPhoneNumber"`
|
||||||
|
ShippingFullAddress string `json:"shippingFullAddress"`
|
||||||
|
CodAmount float64 `json:"codAmount"`
|
||||||
|
ExpectedDeliveryTime string `json:"expectedDeliveryTime"`
|
||||||
|
CreatedDate string `json:"createdDate"`
|
||||||
|
ErrorMessage string `json:"errorMessage"`
|
||||||
|
}
|
|
@ -0,0 +1,295 @@
|
||||||
|
package shiip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.selly.red/Selly-Modules/natsio"
|
||||||
|
"git.selly.red/Selly-Modules/natsio/model"
|
||||||
|
"git.selly.red/Selly-Modules/natsio/subject"
|
||||||
|
"github.com/nats-io/nats.go"
|
||||||
|
|
||||||
|
"git.selly.red/Selly-Modules/3pl/util/httputil"
|
||||||
|
"git.selly.red/Selly-Modules/3pl/util/pjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client ...
|
||||||
|
type Client struct {
|
||||||
|
realm string
|
||||||
|
clientID string
|
||||||
|
clientSecret string
|
||||||
|
|
||||||
|
env ENV
|
||||||
|
natsClient natsio.Server
|
||||||
|
|
||||||
|
token string
|
||||||
|
tokenExpireAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient ...
|
||||||
|
func NewClient(env ENV, clientID, clientSecret, realm string, natsClient natsio.Server) (*Client, error) {
|
||||||
|
if env != EnvProd && env != EnvStaging {
|
||||||
|
return nil, fmt.Errorf("shiip.NewClient: invalid_env %s", env)
|
||||||
|
}
|
||||||
|
return &Client{
|
||||||
|
realm: realm,
|
||||||
|
clientID: clientID,
|
||||||
|
clientSecret: clientSecret,
|
||||||
|
token: "",
|
||||||
|
env: env,
|
||||||
|
natsClient: natsClient,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOutboundRequest ...
|
||||||
|
func (c *Client) CreateOutboundRequest(p OutboundRequestPayload) (*OutboundRequestRes, error) {
|
||||||
|
apiURL := c.getBaseURL() + apiPathCreateOutboundRequest
|
||||||
|
natsPayload := model.CommunicationRequestHttp{
|
||||||
|
ResponseImmediately: true,
|
||||||
|
Payload: model.HttpRequest{
|
||||||
|
URL: apiURL,
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Data: pjson.ToJSONString([]OutboundRequestPayload{p}),
|
||||||
|
Header: c.getRequestHeader(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg, err := c.requestHttpViaNats(natsPayload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.CreateOutboundRequest - requestHttpViaNats: %v, %+v\n", err, natsPayload)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
r model.CommunicationHttpResponse
|
||||||
|
errRes Error
|
||||||
|
dataRes []OutboundRequestRes
|
||||||
|
)
|
||||||
|
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.CreateOutboundRequest: parse_data %v", err)
|
||||||
|
}
|
||||||
|
res := r.Response
|
||||||
|
if res == nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.CreateOutboundRequest: empty_response")
|
||||||
|
}
|
||||||
|
if res.StatusCode >= http.StatusBadRequest {
|
||||||
|
if err = r.ParseResponseData(&errRes); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.CreateOutboundRequest: parse_response_err: %v", err)
|
||||||
|
}
|
||||||
|
return nil, errRes
|
||||||
|
}
|
||||||
|
if err = r.ParseResponseData(&dataRes); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.CreateOutboundRequest: parse_response_data: %v", err)
|
||||||
|
}
|
||||||
|
if len(dataRes) == 0 {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.CreateOutboundRequest: empty_result")
|
||||||
|
}
|
||||||
|
item := &dataRes[0]
|
||||||
|
e := item.Error
|
||||||
|
if e != nil {
|
||||||
|
return nil, errRes
|
||||||
|
}
|
||||||
|
|
||||||
|
return item, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOutboundRequestLogisticInfo ...
|
||||||
|
func (c *Client) UpdateOutboundRequestLogisticInfo(p UpdateORLogisticInfoPayload) error {
|
||||||
|
apiURL := c.getBaseURL() + fmt.Sprintf(apiPathUpdateLogisticInfoOutboundRequest, p.OrID)
|
||||||
|
natsPayload := model.CommunicationRequestHttp{
|
||||||
|
ResponseImmediately: true,
|
||||||
|
Payload: model.HttpRequest{
|
||||||
|
URL: apiURL,
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Header: c.getRequestHeader(),
|
||||||
|
Data: pjson.ToJSONString(p),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg, err := c.requestHttpViaNats(natsPayload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.UpdateOutboundRequestLogisticInfo - requestHttpViaNats: %v, %+v\n", err, natsPayload)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
r model.CommunicationHttpResponse
|
||||||
|
errRes Error
|
||||||
|
)
|
||||||
|
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
|
||||||
|
return fmt.Errorf("shiip.Client.UpdateOutboundRequestLogisticInfo: parse_data %v", err)
|
||||||
|
}
|
||||||
|
res := r.Response
|
||||||
|
if res == nil {
|
||||||
|
return fmt.Errorf("shiip.Client.UpdateOutboundRequestLogisticInfo: empty_response")
|
||||||
|
}
|
||||||
|
if res.StatusCode >= http.StatusBadRequest {
|
||||||
|
if err = r.ParseResponseData(&errRes); err != nil {
|
||||||
|
return fmt.Errorf("shiip.Client.UpdateOutboundRequestLogisticInfo: parse_response_err: %v", err)
|
||||||
|
}
|
||||||
|
return errRes
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOutboundRequestByID ...
|
||||||
|
func (c *Client) GetOutboundRequestByID(requestID int) (*OutboundRequestInfo, error) {
|
||||||
|
apiURL := c.getBaseURL() + fmt.Sprintf(apiPathGetOutboundRequest, requestID)
|
||||||
|
natsPayload := model.CommunicationRequestHttp{
|
||||||
|
ResponseImmediately: true,
|
||||||
|
Payload: model.HttpRequest{
|
||||||
|
URL: apiURL,
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Header: c.getRequestHeader(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg, err := c.requestHttpViaNats(natsPayload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.GetOutboundRequestByID - requestHttpViaNats: %v, %+v\n", err, natsPayload)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
r model.CommunicationHttpResponse
|
||||||
|
errRes Error
|
||||||
|
outboundRequest OutboundRequestInfo
|
||||||
|
)
|
||||||
|
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.GetOutboundRequestByID: parse_data %v", err)
|
||||||
|
}
|
||||||
|
res := r.Response
|
||||||
|
if res == nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.GetOutboundRequestByID: empty_response")
|
||||||
|
}
|
||||||
|
if res.StatusCode >= http.StatusBadRequest {
|
||||||
|
if err = r.ParseResponseData(&errRes); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.GetOutboundRequestByID: parse_response_err: %v", err)
|
||||||
|
}
|
||||||
|
return nil, errRes
|
||||||
|
}
|
||||||
|
if err = r.ParseResponseData(&outboundRequest); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.GetOutboundRequestByID: parse_response_data: %v", err)
|
||||||
|
}
|
||||||
|
return &outboundRequest, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelOutboundRequest ...
|
||||||
|
func (c *Client) CancelOutboundRequest(requestID int, note string) error {
|
||||||
|
apiURL := c.getBaseURL() + fmt.Sprintf(apiPathCancelOutboundRequest, requestID)
|
||||||
|
data := map[string]string{"note": note}
|
||||||
|
natsPayload := model.CommunicationRequestHttp{
|
||||||
|
ResponseImmediately: true,
|
||||||
|
Payload: model.HttpRequest{
|
||||||
|
URL: apiURL,
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Header: c.getRequestHeader(),
|
||||||
|
Data: pjson.ToJSONString(data),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg, err := c.requestHttpViaNats(natsPayload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.CancelOutboundRequest - requestHttpViaNats: %v, %+v\n", err, natsPayload)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
r model.CommunicationHttpResponse
|
||||||
|
errRes Error
|
||||||
|
)
|
||||||
|
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
|
||||||
|
return fmt.Errorf("shiip.Client.CancelOutboundRequest: parse_data %v", err)
|
||||||
|
}
|
||||||
|
res := r.Response
|
||||||
|
if res == nil {
|
||||||
|
return fmt.Errorf("shiip.Client.CancelOutboundRequest: empty_response")
|
||||||
|
}
|
||||||
|
if res.StatusCode >= http.StatusBadRequest {
|
||||||
|
if err = r.ParseResponseData(&errRes); err != nil {
|
||||||
|
return fmt.Errorf("shiip.Client.CancelOutboundRequest: parse_response_err: %v", err)
|
||||||
|
}
|
||||||
|
return errRes
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) auth() (*authRes, error) {
|
||||||
|
b := AuthPayload{
|
||||||
|
ClientID: c.clientID,
|
||||||
|
ClientSecret: c.clientSecret,
|
||||||
|
}
|
||||||
|
header := map[string]string{
|
||||||
|
httputil.HeaderKeyContentType: httputil.HeaderValueApplicationJSON,
|
||||||
|
}
|
||||||
|
apiURL := baseURLAuthENVMapping[c.env] + apiPathAuth
|
||||||
|
natsPayload := model.CommunicationRequestHttp{
|
||||||
|
ResponseImmediately: true,
|
||||||
|
Payload: model.HttpRequest{
|
||||||
|
URL: apiURL,
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Data: pjson.ToJSONString(b),
|
||||||
|
Header: header,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
msg, err := c.requestHttpViaNats(natsPayload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.auth - requestHttpViaNats: %v, %+v\n", err, natsPayload)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
r model.CommunicationHttpResponse
|
||||||
|
errRes Error
|
||||||
|
data authRes
|
||||||
|
)
|
||||||
|
if err = pjson.Unmarshal(msg.Data, &r); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.auth: parse_data %v", err)
|
||||||
|
}
|
||||||
|
res := r.Response
|
||||||
|
if res == nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.auth: empty_response")
|
||||||
|
}
|
||||||
|
if res.StatusCode >= http.StatusBadRequest {
|
||||||
|
if err = r.ParseResponseData(&errRes); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.auth: parse_response_err: %v", err)
|
||||||
|
}
|
||||||
|
return nil, errRes
|
||||||
|
}
|
||||||
|
if err = r.ParseResponseData(&data); err != nil {
|
||||||
|
return nil, fmt.Errorf("shiip.Client.auth: parse_response_data: %v", err)
|
||||||
|
}
|
||||||
|
return &data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getRequestHeader() map[string]string {
|
||||||
|
m := map[string]string{
|
||||||
|
httputil.HeaderKeyContentType: httputil.HeaderValueApplicationJSON,
|
||||||
|
}
|
||||||
|
token, err := c.getToken()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("shiip.Client.getToken: %v\n", err)
|
||||||
|
} else {
|
||||||
|
m["Authorization"] = fmt.Sprintf("Bearer %s", token)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) requestHttpViaNats(data model.CommunicationRequestHttp) (*nats.Msg, error) {
|
||||||
|
b := pjson.ToBytes(data)
|
||||||
|
return c.natsClient.Request(subject.Communication.RequestHTTP, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getBaseURL() string {
|
||||||
|
return baseURLENVMapping[c.env]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getToken() (string, error) {
|
||||||
|
if c.token != "" || c.tokenExpireAt.After(time.Now()) {
|
||||||
|
return c.token, nil
|
||||||
|
}
|
||||||
|
data, err := c.auth()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
c.token = data.AccessToken
|
||||||
|
d := time.Duration(data.ExpiresIn) * time.Second
|
||||||
|
if d.Minutes() > 30 {
|
||||||
|
d -= 30 * time.Minute
|
||||||
|
}
|
||||||
|
c.tokenExpireAt = time.Now().Add(d)
|
||||||
|
return c.token, nil
|
||||||
|
}
|
|
@ -20,8 +20,9 @@ const (
|
||||||
baseURLStag = "https://stg-gw.viettelpost.vn"
|
baseURLStag = "https://stg-gw.viettelpost.vn"
|
||||||
baseURLAuthStag = "https://stg-keycloak.viettelpost.vn"
|
baseURLAuthStag = "https://stg-keycloak.viettelpost.vn"
|
||||||
|
|
||||||
baseURLProd = "https://gw.viettelpost.vn"
|
// TODO: update prod url
|
||||||
baseURLAuthProd = "https://dws-sso.viettelpost.vn"
|
baseURLProd = ""
|
||||||
|
baseURLAuthProd = ""
|
||||||
|
|
||||||
pathAuth = "/realms/wms/protocol/openid-connect/token"
|
pathAuth = "/realms/wms/protocol/openid-connect/token"
|
||||||
pathUpdateORLogisticInfo = "/wms-core/api/v1/obms/outbound-request/outbound-request-partner/%s"
|
pathUpdateORLogisticInfo = "/wms-core/api/v1/obms/outbound-request/outbound-request-partner/%s"
|
||||||
|
|
|
@ -2,15 +2,14 @@ package pjson
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
"git.selly.red/Selly-Modules/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToBytes ...
|
// ToBytes ...
|
||||||
func ToBytes(data interface{}) []byte {
|
func ToBytes(data interface{}) []byte {
|
||||||
b, err := json.Marshal(data)
|
b, err := json.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("pjson.ToBytes", logger.LogData{"payload": data})
|
log.Printf("3pl/util/pjson.ToBytes.Marshal: %v\n", err)
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue