diff --git a/engine/suretax.go b/engine/suretax.go index 4f4720ba4..fda552d93 100644 --- a/engine/suretax.go +++ b/engine/suretax.go @@ -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 // Client’s 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) diff --git a/engine/suretax_test.go b/engine/suretax_test.go index a01b203a3..5273d6fa3 100644 --- a/engine/suretax_test.go +++ b/engine/suretax_test.go @@ -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]) } } diff --git a/general_tests/suretax_it_test.go b/general_tests/suretax_it_test.go index ba4a44f25..ddcb87065 100644 --- a/general_tests/suretax_it_test.go +++ b/general_tests/suretax_it_test.go @@ -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) } } +*/ diff --git a/general_tests/tutorial_local_test.go b/general_tests/tutorial_local_test.go index d4e404915..255acc4cf 100644 --- a/general_tests/tutorial_local_test.go +++ b/general_tests/tutorial_local_test.go @@ -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())