Compare commits
	
		
			No commits in common. "5aebf6a070ab01501d1cee3b1ea27a2f970aff6a" and "38b82067c7002f621a53291bbb30a0fabd2de48a" have entirely different histories.
		
	
	
		
			5aebf6a070
			...
			38b82067c7
		
	
		| 
						 | 
					@ -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 := pjson.ToBytes(data)
 | 
						b := toBytes(data)
 | 
				
			||||||
	return c.natsClient.Request(subject, b)
 | 
						return c.natsClient.Request(subject, b)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,27 @@ 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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,54 +0,0 @@
 | 
				
			||||||
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,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
package shiip
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ENV ...
 | 
					 | 
				
			||||||
type ENV string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	EnvStaging ENV = "STAGING"
 | 
					 | 
				
			||||||
	EnvProd    ENV = "PROD"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,62 +0,0 @@
 | 
				
			||||||
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"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,57 +0,0 @@
 | 
				
			||||||
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"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,295 +0,0 @@
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,14 +2,15 @@ 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 {
 | 
				
			||||||
		log.Printf("3pl/util/pjson.ToBytes.Marshal: %v\n", err)
 | 
							logger.Error("pjson.ToBytes", logger.LogData{"payload": data})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return b
 | 
						return b
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue