Encapsulate SureTax Request and Response objects

This commit is contained in:
DanB
2015-10-26 19:07:03 +01:00
parent 222bd65286
commit 6494284b58
4 changed files with 42 additions and 17 deletions

View File

@@ -51,7 +51,7 @@ func NewSureTaxRequest(cdr *StoredCdr, stCfg *config.SureTaxCfg) (*SureTaxReques
if len(definedTaxExtempt) != 0 {
taxExempt = strings.Split(cdr.FieldsAsString(stCfg.TaxExemptionCodeList), ",")
}
stReq := new(SureTaxRequest)
stReq := new(STRequest)
stReq.ClientNumber = stCfg.ClientNumber
stReq.BusinessUnit = "" // Export it to config
stReq.ValidationKey = stCfg.ValidationKey
@@ -85,11 +85,15 @@ func NewSureTaxRequest(cdr *StoredCdr, stCfg *config.SureTaxCfg) (*SureTaxReques
TaxExemptionCodeList: taxExempt,
},
}
return stReq, nil
return &SureTaxRequest{Request: stReq}, nil
}
type SureTaxRequest struct {
Request *STRequest // SureTax Requires us to encapsulate the content into a request element
}
// SureTax Request type
type SureTaxRequest struct {
type STRequest struct {
ClientNumber string // Client ID Number provided by SureTax. Required. Max Len: 10
BusinessUnit string // Clients Business Unit. Value for this field is not required. Max Len: 20
ValidationKey string // Validation Key provided by SureTax. Required for client access to API function. Max Len: 36
@@ -131,6 +135,10 @@ type STRequestItem struct {
// SureTax Response type
type SureTaxResponse struct {
D *STResponse // SureTax requires encapsulating reply into a D object
}
type STResponse struct {
Successful string // Response will be either Y' or N' : Y = Success / Success with Item error N = Failure
ResponseCode int64 // ResponseCode: 9999 Request was successful. 1101-1400 Range of values for a failed request (no processing occurred) 9001 Request was successful, but items within the request have errors. The specific items with errors are provided in the ItemMessages field.
HeaderMessage string // Response message: For ResponseCode 9999 “Success”For ResponseCode 9001 “Success with Item errors”. For ResponseCode 1100-1400 Unsuccessful / declined web request.
@@ -164,6 +172,7 @@ type STTaxItem struct {
}
func SureTaxProcessCdr(cdr *StoredCdr) error {
fmt.Printf("SureTaxProcessCdr, cdr: %+v\n", cdr)
stCfg := config.CgrConfig().SureTaxCfg()
if stCfg == nil {
return errors.New("Invalid SureTax configuration")
@@ -182,34 +191,36 @@ func SureTaxProcessCdr(cdr *StoredCdr) error {
if err != nil {
return err
}
utils.Logger.Debug(fmt.Sprintf("###SureTax NewSureTaxRequest to: %s, body: %+v, ItemList: %+v\n", stCfg.Url, req, req.ItemList[0]))
body := append([]byte("request="), jsnContent...)
resp, err := sureTaxClient.Post(stCfg.Url, "application/x-www-form-urlencoded", bytes.NewBuffer(body))
fmt.Printf("NewSureTaxRequest: %s\n", string(jsnContent))
resp, err := sureTaxClient.Post(stCfg.Url, "application/json", bytes.NewBuffer(jsnContent))
if err != nil {
return err
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Unexpected response body received, error: %s\n", err.Error())
return err
}
if resp.StatusCode > 299 {
fmt.Printf("Unexpected code received: %d\n", resp.StatusCode)
return fmt.Errorf("Unexpected status code received: %d", resp.StatusCode)
}
fmt.Printf("Received raw answer from SureTax: %s\n", string(respBody))
var stResp SureTaxResponse
if err := json.Unmarshal(respBody, &stResp); err != nil {
return err
}
utils.Logger.Debug(fmt.Sprintf("###SureTax received response: %+v\n", stResp))
if stResp.ResponseCode != 9999 {
cdr.ExtraInfo = stResp.HeaderMessage
fmt.Printf("Received answer from SureTax: %+v\n", stResp)
if stResp.D.ResponseCode != 9999 {
cdr.ExtraInfo = stResp.D.HeaderMessage
return nil // No error because the request was processed by SureTax, error will be in the ExtraInfo
}
// Write cost to CDR
if !stCfg.IncludeLocalCost {
cdr.Cost = utils.Round(stResp.TotalTax, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE)
cdr.Cost = utils.Round(stResp.D.TotalTax, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE)
} else {
cdr.Cost = utils.Round(cdr.Cost+stResp.TotalTax, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE)
cdr.Cost = utils.Round(cdr.Cost+stResp.D.TotalTax, config.CgrConfig().RoundingDecimals, utils.ROUNDING_MIDDLE)
}
// Add response into extra fields to be available for later review
cdr.ExtraFields[utils.META_SURETAX] = string(respBody)

View File

@@ -40,7 +40,7 @@ func TestNewSureTaxRequest(t *testing.T) {
stCfg.ClientNumber = "000000000"
stCfg.ValidationKey = "19491161-F004-4F44-BDB3-E976D6739A64"
stCfg.Timezone = time.UTC
eSureTaxRequest := &SureTaxRequest{
eSureTaxRequest := &SureTaxRequest{Request: &STRequest{
ClientNumber: "000000000",
ValidationKey: "19491161-F004-4F44-BDB3-E976D6739A64",
DataYear: "2013",
@@ -69,10 +69,10 @@ func TestNewSureTaxRequest(t *testing.T) {
TaxExemptionCodeList: []string{},
},
},
}
}}
if stReq, err := NewSureTaxRequest(cdr, stCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eSureTaxRequest, stReq) {
t.Errorf("Expecting: %+v, received: %+v", eSureTaxRequest.ItemList[0], stReq.ItemList[0])
t.Errorf("Expecting: %+v, received: %+v", eSureTaxRequest.Request.ItemList[0], stReq.Request.ItemList[0])
}
}

View File

@@ -76,6 +76,7 @@ func TestSTIResetStorDb(t *testing.T) {
}
}
/*
// Start CGR Engine
func TestSTIStartEngine(t *testing.T) {
if !*testSureTax {
@@ -85,6 +86,7 @@ func TestSTIStartEngine(t *testing.T) {
t.Fatal(err)
}
}
*/
// Connect rpc client to rater
func TestSTIRpcConn(t *testing.T) {
@@ -92,7 +94,7 @@ func TestSTIRpcConn(t *testing.T) {
return
}
var err error
stiRpc, err = jsonrpc.Dial("tcp", stiCfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
stiRpc, err = jsonrpc.Dial("tcp", "172.16.254.70:2012") // We connect over JSON so we can also troubleshoot if needed // stiCfg.RPCJSONListen
if err != nil {
t.Fatal(err)
}
@@ -145,7 +147,7 @@ func TestSTIProcessExternalCdr(t *testing.T) {
} else if reply != utils.OK {
t.Error("Unexpected reply received: ", reply)
}
time.Sleep(time.Duration(*waitRater) * time.Millisecond)
time.Sleep(time.Duration(2) * time.Second)
}
func TestSTIGetCdrs(t *testing.T) {
@@ -163,8 +165,19 @@ func TestSTIGetCdrs(t *testing.T) {
t.Errorf("Unexpected Cost for CDR: %+v", cdrs[0])
}
}
req = utils.RpcCdrsFilter{RunIds: []string{utils.META_SURETAX}, Accounts: []string{"1001"}}
if err := stiRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
t.Error("Unexpected error: ", err.Error())
} else if len(cdrs) != 1 {
t.Error("Unexpected number of CDRs returned: ", len(cdrs))
} else {
if cdrs[0].Cost != 0.012 {
t.Errorf("Unexpected Cost for CDR: %+v", cdrs[0])
}
}
}
/*
func TestSTIStopCgrEngine(t *testing.T) {
if !*testSureTax {
return
@@ -173,3 +186,4 @@ func TestSTIStopCgrEngine(t *testing.T) {
t.Error(err)
}
}
*/

View File

@@ -663,7 +663,7 @@ func TestTutLocalCostErrors(t *testing.T) {
} else if reply != utils.OK {
t.Error("Unexpected reply received: ", reply)
}
time.Sleep(time.Duration(*waitRater) * time.Millisecond) // Give time for CDR to be processed
req = utils.RpcCdrsFilter{RunIds: []string{utils.META_DEFAULT}, Accounts: []string{cdr2.Account}, DestPrefixes: []string{cdr2.Destination}}
if err := tutLocalRpc.Call("ApierV2.GetCdrs", req, &cdrs); err != nil {
t.Error("Unexpected error: ", err.Error())