DEBUG|{"type":"SalesOrder","lines":[\{"quantity":1.00,"itemCode":"43490","description":"Freight","number":"1","amount":0.00},\{"quantity":1.00,"itemCode":"79345","description":"Puggles Backpack","number":"2","amount":4.1677967793}],"customerCode":"4","companyCode":"awana1","code":"988103","date":"2018-04-25 10:29:52","commit":"false","addresses":{"ShipTo":{"region":"BC","postalCode":"V4P 1H5","line1":"2430 King George Blvd Ste 101","country":null,"city":"Surrey"},"ShipFrom":{"region":"IL","postalCode":"60173","line1":"1620 N Penny Ln","country":"US","city":"Schaumburg"}}}
10:29:51.0 (36237563)|CALLOUT_REQUEST|[1747]|System.HttpRequest[Endpoint=callout:AvalaraTax, Method=POST]
10:29:51.0 (40289120)|EXCEPTION_THROWN|[1747]|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
10:29:51.0 (40477323)|FATAL_ERROR|System.UnexpectedException: Invalid parameter value "fB0Ni1BVtLnbAD1xVS1udw==" for parameter "Decryption Exception".
The Apex code that makes the call out to Avalara is this:
webservice static Result CalculateTaxOnOpportunity(string OrderId)
{
decimal TaxAmount = null;
// Try to
try
{
// Convert the OpportunitySalesforceId argument provided to a Salesforce ID
ID TempId = OrderId;
// If converting fails, return failure and an error message.
} catch(Exception ex) { return new Result(false,'Please supply a valid Order (15 or 18 character) Salesforce Id. Error Message: '+ex.getMessage()); }
try
{
// Initialize the tax variable to zero.
TaxAmount = 0;
AvalaraTaxJSON Obj = new AvalaraTaxJSON(OrderId);
if(Obj.companyCode != null || Obj.companyCode !='') {
string jsonData = JSON.serialize(Obj);
jsonData = jsonData.replace('AvalaraCurrentDataTime','date');
jsonData = jsonData.replace('Avalara_Commit','commit');
jsonData = jsonData.replaceAll('Avalara_SeqNumber','number');
system.debug(jsonData);
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AvalaraTax');
req.setBody(jsonData);
req.setHeader('Content-Type','application/json');
req.setMethod('POST');
HttpResponse res = h.send(req);
system.debug(res.getBody());
JSONParser parser = JSON.createParser(res.getBody());
while (parser.nextToken() != null) {
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
(parser.getText() == 'totalTax')) {
parser.nextToken();
TaxAmount = parser.getDecimalValue();
}
}
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
else
return new Result(false,'The Order must have a valid Shipping Country before calculating tax OR Country must be United States Or Canada');
}
// If an error occurred getting tax
catch (Exception ex)
{
// Return failure and an error message.
return new Result(false,'An error occurred when getting tax from the tax system. Error:'+ex.getMessage());
}
// Otherwise, return Success as true and the Tax Amount calculated by the tax web service.*/
return new Result(true,'Success, tax amount calculated',TaxAmount);
}
The AvalaraTaxJSON object looks like this:
public class AvalaraTaxJSON {
string code;
public string companyCode{get;set;}
string type;
string AvalaraCurrentDataTime;
string customerCode;
string Avalara_Commit;
address addresses;
list<lineItem> lines;
public class address{
public AddressCls ShipFrom;
public AddressCls ShipTo;
}
public class AddressCls{
string line1;
string city;
string region;
string country;
string postalCode;
public AddressCls(string line, string city, string reg, string country, string zipCode){
this.line1 = line;
this.city = city;
this.region = reg;
this.country = country;
this.postalCode = zipCode;
}
}
public class lineItem{
public string Avalara_SeqNumber;
public decimal quantity;
public decimal amount;
public string description;
public string itemCode;
public lineItem(string num,decimal qunt, decimal amt,string itemCode, string des){
this.Avalara_SeqNumber = num;
this.quantity = qunt;
this.amount =amt;
this.description = des;
this.itemCode = itemcode;
}
}
public AvalaraTaxJSON(string orderId){
string isoCode;
//Constructing JSON with OrderLine Items
lines = new list<LineItem>();
list<Order> orderLst = [SELECT ID, Name,Shipping_Street__c, Shipping_City__c,Shipping_State__c, Shipping_Zip_Code__c, Shipping_Country__c, TempOrderNumber__c, LastModifiedById, Error_Log__c,Account.IntacctID__c, Company__c,
(SELECT Line_Type__c, PricebookEntry.Product2Id, PricebookEntry.Product2.ProductCode, PricebookEntry.Product2.Name, Quantity, TotalPrice, Quantity_Given_Away__c FROM Order.OrderItems) FROM Order WHERE ID = :string.escapeSingleQuotes(orderId)];
if(orderLst!=null&& orderLst.size()>0){
Order Ord= orderLst.get(0);
if(Ord.Shipping_Country__c!=null && Ord.Shipping_Country__c.toLowerCase().contains('united states') || Ord.Shipping_Country__c.toLowerCase().contains('canada')){
list<Country__c> countryObj = [SELECT ISO_Code__c FROM Country__c WHERE Name = :Ord.Shipping_Country__c];
if(countryObj!=null && countryObj.size()>0){
isoCode = countryObj.get(0).ISO_Code__c;
}
Awana_Settings__c custSetting = Awana_Settings__c.getValues('AvalaraTaxCompany');
if(custSetting!=null)
this.companyCode = custSetting.value__c;
else
this.companyCode = 'awana1-sb2'; //default value
this.code = Ord.TempOrderNumber__c;
this.customerCode = Ord.Account.IntacctID__c;
this.type = 'SalesOrder';
this.AvalaraCurrentDataTime = String.valueOf(system.now());
this.Avalara_Commit = 'false';
addresses = new address();
addresses.ShipFrom = new AddressCls('1620 N Penny Ln','Schaumburg','IL','US','60173'); //Default Address Present in Cast iron
addresses.ShipTo = new AddressCls(Ord.Shipping_Street__c,Ord.Shipping_City__c,Ord.Shipping_State__c,isoCode,Ord.Shipping_Zip_Code__c);
integer itr =1;
for(OrderItem oli : Ord.OrderItems){
lines.add(new LineItem(string.valueOf(itr),oli.Quantity,Oli.TotalPrice,oli.PricebookEntry.Product2.ProductCode,oli.PricebookEntry.Product2.Name));
itr++;
}
}
}
}
}