Customizing Quickbooks Connector

If you want to extend or amend the out-of-the-box functionality that is offered from our Quickbooks connector, you can do so by following the process described on this page. The extensions you can do is to change the mapping between the interworks.cloud and Quickbooks entities or to implement new push and pull methods that are not currently supported by our connector.

Registering a new Integration Connector


You must start by creating a new integration connector following the instructions described in page Register a New Integration Connector.


Uploading the JSON file of our Quickbooks Connector


When you register a new connector, a sample JSON Specification will be pre-filled. You must replace this JSON file with the file Quickbooks_JSON.txt

For doing this you must open the registered connector and in definition area to switch to Text for copying the JSON file you downloaded.


Save your connector and then you will be able to make any changes you wish by following the instructions described in Integrate to interworks.cloud guide


Manage Sales-Tax Calculation for Non-US & Non-EU locales


It has come to our attention that Quickbooks has an issue when it comes to correctly capturing and depicting the information of the invoice’s total amount, due to missing taxation information that caused the total amount (of an invoice) to be miscalculated and the reason behind all the above was caused by a non-exposed Quickbooks’ JSON field, contained inside the connector (when attempting pre-synchronization actions via API calls), and occurs only to NON-US as well as NON-EU customers. The information was not being passed from BSS to Quickbooks and as a result, the generated invoice had a miscalculated total amount since the field responsible for communicating the taxation number was never being received by the Quickbooks platform of the customer.

Two Steps for Eliminating the Sales-Tax Calculation Issue

To eliminate this issue, we have decided to first introduce a new adjustable custom fields (created inside the BSS account) that will contain the taxation information of the account and second to alter the JSON file to only push to Quickbooks the net amount of the generated invoice and along with the custom field (containing the taxation details for a given invoice, based on the account’s set taxation percentage), they will both ‘feed’ the Quickbooks platform into performing the final calculation of the total amount (Net+VAT) of the invoice.


Step One

The BSS user responsible for the creation of the import of a new customer inside our BSS platform will also configure manually the new account’s custom fields. This new custom field will retain the taxation percentage of that customer so that it will later be utilized by Quickbooks during the invoice’s total amount calculation and generation for that customer. Please proceed with the following solution, to create an account custom fields:


  1. Login into interworks.cloud BSS and access the Setup mode. Then from the main menu, go to the "Office" tab and choose the "Account" option. In the Account module, under the section "Other Customizations" click on "Custom Fields". 


  2. On the "Custom Fields" screen click on the "Add" button. A new pop up window appears. 



  3. Complete the necessary information of the new account custom field. Below you will find the most basic details for the new field as well as the values that you need to fill in:

    Name: The name of the field that will be displayed at the BSS account should have a name such as "Tax 15%" or "VAT 15%" so that it is clear. 

    Type: The type of the value should be "Boolean". Choose the option from the drop-down menu. 

    Group: The group the field will belong to should be "Custom Fields". Choose the option from the drop-down menu. 

    Ordering: If there is more than one field at the group, this signifies the ordering rank. Not important in our case.

    Value Suffix: Please leave it as is (empty). 

    Description: In this free-text box you can write anything relative to the custom field, that will help you remember its use.

    Compulsory field: If this field is compulsory, it will have to be filled. You can enable it if you wish, but it is not important in our case.

    Set custom field as search criterion: This enables the use of the field at the search facility of the system. You can enable it if you wish, but it is not important in our case.

    Display Rule (selection): Please leave it as is (default [Select...]).

    Default Value: Signifies a specific, 'default' value for every entity. Please leave it as is (disabled). 

  4. After you have finished with the completion of the information on the new account custom field you can click on the "Save and Close" option at the bottom of the pop-up window.

  5. After you have finished with the creation of the account's custom field you may proceed with the second step.


Step Two

The following instructions are implemented within the JSON file and are necessary changes because they will alter the communication between our BSS platform and the Quickbooks platform for the (correct) taxation calculation to take effect on the Quickbooks side and not on our BSS side. Some of the JSON changes are carried out by our support team. However, you should proceed with doing part of the changes yourself by following the instructions below.

There are two sets of necessary changes that the following instructions, guide the user to perform. 

  1. To proceed with the first set of the necessary changes, please log in to interworks.cloud BSS and access the Setup mode. Then from the main menu, go to: Administration (tab)  System Options (option)  Integration Systems (section)  Systems Setup (option)  Enabled Connectors (section)  Quickbooks (system)  Edit integration (button) Transformation Helper (section).


  2. Under the "Transformation Helper" section of the page, there is a drop-down list in which you must choose the option "invoiceRequest". Upon choosing this option the box below is populated with the corresponding part of the JSON in which the changes will take effect. The following code is an example of what the code will look like:

    invoiceRequest
    {
      "MetaData": {
        "CreateTime": "#valueof($.invoice.createdAt)",
        "LastUpdatedTime": "#valueof($.invoice.updatedAt)"
      },
      "TxnDate": "#valueof($.invoice.invoiceDate)",
      "Line": {
        "#loop($.invoice.invoiceItems)": {
          "Id": "#add(#currentindex(),1)",
          "Amount": "#CalculateFinalPrice(#currentvalueatpath($.invoiceItemTaxes),#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",  <<<<<<<<<<<<<<<<<<<<<<<
          "DetailType": "#valueof($.serverVariables.invoice_Detail_Type)",
          "SalesItemLineDetail": {
            "ItemRef": {
              "value": "#currentvalueatpath($.product.integrationId)",
              "name": "#currentvalueatpath($.product.name)"
            },
            "UnitPrice": "#currentvalueatpath($.unitPrice)",
            "Qty": "#currentvalueatpath($.quantity)"
          }
        }
      },
      "CustomerRef": {
        "value": "#valueof($.invoice.account.integrationId)",
        "name": "#valueof($.invoice.account.name)"
      },
      "BillAddr": {
        "Line1": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address1)",
        "Line2": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address2)",
        "City": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].city)",
        "Country": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].countryName)",
        "PostalCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].postCode)",
        "CountrySubDivisionCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].region)"
      },
      "DueDate": "#valueof($.invoice.dueDate)",
      "TotalAmt": "#valueof($.invoice.totalAmount)",
      "CurrencyRef": {
        "value": "#valueof($.invoice.account.currency.mnemonic)",
        "name": "#valueof($.invoice.account.currency.name)"
      },
      "BillEmail": {
        "Address": "#valueof($.invoice.billingAccount.corpEmail)"
      },
      "Balance": "#valueof($.invoice.balance)"
    }



  3. Please locate the line writing " ' "Amount": "#CalculateFinalPrice... ' ", as depicted in the code example above with the "<<<<<<<<<<<<<<<<<<<<<<<" marks.
    The first of the two lines that the changes will occur (in our example) is this: ' "Amount": "#CalculateFinalPrice(#currentvalueatpath($.invoiceItemTaxes),#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))", '

    A quick explanation of the line: This JSON line calculates the Final Price of the generated invoice inside our BSS platform, by multiplying the "unit price" to the "quantity" and then adds at the end the tax percentage accordingly on that price. By removing the TAX entity from the calculation the BSS will no longer push the incorrect Final Price, rather it will push the Net amount along with the quantity of the products towards the Quickbooks platform.   
    Consequently, in this line, you must remove the part that has inside the parenthesis the taxation/VAT value path so that the changed line will look like this:

    New Amount line
    "Amount": "#CalculateFinalPrice(,#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",



  4. Now some lines must be added after the line with the "Amount" calculation mentioned above. The line of code that needs to be added inside the JSON was added by us so that we can push the taxation information towards the Quickbooks platform as mentioned at the beginning of the issue's explanation.

    Please locate the line writing "TaxCodeRef" and the one below it writing "value", as depicted in the exemplary code below with the "<<<<<<<<<<<<<<<<<<<<<<<" marks, provided by us.
    You will have to alter it and then copy and paste it within your BSS JSON code, but first, read the logic of the line below (#5) before continuing with the addition of the lines inside your JSON code.

    InvoiceRequest
    {
      "MetaData": {
        "CreateTime": "#valueof($.invoice.createdAt)",
        "LastUpdatedTime": "#valueof($.invoice.updatedAt)"
      },
      "TxnDate": "#valueof($.invoice.invoiceDate)",
      "Line": {
        "#loop($.invoice.invoiceItems)": {
          "Id": "#add(#currentindex(),1)",
          "Amount": "#CalculateFinalPrice(,#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",
          "DetailType": "#valueof($.serverVariables.invoice_Detail_Type)",
          "SalesItemLineDetail": {
            "TaxCodeRef": {														                                                     <<<<<<<<<<<<<<<<<<<<<<<
              "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='VAT 15%')].value),1,14,10)"   <<<<<<<<<<<<<<<<<<<<<<<
            },
            "ItemRef": {
              "value": "#currentvalueatpath($.product.integrationId)",
              "name": "#currentvalueatpath($.product.name)"
            },
            "UnitPrice": "#currentvalueatpath($.unitPrice)",
            "Qty": "#currentvalueatpath($.quantity)"
          }
        }
      },
      "CustomerRef": {
        "value": "#valueof($.invoice.account.integrationId)",
        "name": "#valueof($.invoice.account.name)"
      },
      "BillAddr": {
        "Line1": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address1)",
        "Line2": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address2)",
        "City": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].city)",
        "Country": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].countryName)",
        "PostalCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].postCode)",
        "CountrySubDivisionCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].region)"
      },
      "DueDate": "#valueof($.invoice.dueDate)",
      "TotalAmt": "#valueof($.invoice.totalAmount)",
      "CurrencyRef": {
        "value": "#valueof($.invoice.account.currency.mnemonic)",
        "name": "#valueof($.invoice.account.currency.name)"
      },
      "BillEmail": {
        "Address": "#valueof($.invoice.billingAccount.corpEmail)"
      },
      "Balance": "#valueof($.invoice.balance)"
    }



  5. The second of the two lines that the changes will occur (in our example) is this: ' "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='VAT 15%')].value),1,14,10)" '.
    A quick explanation of the line: This JSON line has an "if" statement that if True, will push the value of the account's custom field with the name " 'VAT 15%' " towards the Quickbooks platform. The value will contain for example the number 15. The last number located at the end of the line "1,14,10" have the following meaning: 

    Name
    : "VAT 15%" → The name of the account custom field corresponding to a fifteen percent (15%) VAT value.
    First Number: "1"→ Means that the "if" condition is true.
    Second Number: "14"→ Is the value that will be sent to Quickbooks as a "TaxCodeRef ID" when the "if" condition is true.
    Third Number: "10" → Is the value that will be sent to Quickbooks as a "TaxCodeRef ID" when the "if" condition is false.

    Consequently, the lines that, you must add under inside the "SalesItemLineDetail" line will look like this:

    "SalesItemLineDetail": {
            "TaxCodeRef": {														                                                     
              "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='TAX 15%')].value),1,14,10)"
            },
    

    Lastly, after you have finished configuring the "invoiceRequest" method, please click on the "Save Transformation" button to save the changes.


  6. To proceed with the second set of the necessary changes, while inside the Quickbooks Edit integration page and looking at the Transformation Helper (section), choose from the drop-down list the option "invoiceUpdateRequest".



  7. Upon choosing this option the box below is populated with the corresponding part of the JSON in which the last changes will take effect. The following code is an example of what the code will look like:

    invoiceUpdateRequest
    {
      "SyncToken": "#valueof($.preSyncrhonization.syncToken)",
      "Id": "#valueof($.invoice.integrationId)",
      "MetaData": {
        "CreateTime": "#valueof($.invoice.createdAt)",
        "LastUpdatedTime": "#valueof($.invoice.updatedAt)"
      },
      "TxnDate": "#valueof($.invoice.invoiceDate)",
      "Line": {
        "#loop($.invoice.invoiceItems)": {
          "Id": "#add(#currentindex(),1)",
          "Amount": "#CalculateFinalPrice(#currentvalueatpath($.invoiceItemTaxes),#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",  <<<<<<<<<<<<<<<<<<<<<<<<<<<<
          "DetailType": "#valueof($.serverVariables.invoice_Detail_Type)",
          "SalesItemLineDetail": {
            "ItemRef": {
              "value": "#currentvalueatpath($.product.integrationId)",
              "name": "#currentvalueatpath($.product.name)"
            },
            "UnitPrice": "#currentvalueatpath($.finalPrice)",
            "Qty": "#currentvalueatpath($.quantity)"
          }
        }
      },
      "CustomerRef": {
        "value": "#valueof($.invoice.account.integrationId)",
        "name": "#valueof($.invoice.account.name)"
      },
      "BillAddr": {
        "Line1": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address1)",
        "Line2": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address2)",
        "City": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].city)",
        "Country": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].countryName)",
        "PostalCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].postCode)",
        "CountrySubDivisionCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].region)"
      },
      "DueDate": "#valueof($.invoice.dueDate)",
      "TotalAmt": "#valueof($.invoice.totalAmount)",
      "CurrencyRef": {
        "value": "#valueof($.invoice.account.currency.mnemonic)",
        "name": "#valueof($.invoice.account.currency.name)"
      },
      "BillEmail": {
        "Address": "#valueof($.invoice.billingAccount.corpEmail)"
      },
      "Balance": "#valueof($.invoice.balance)",
      "sparse": true
    }




  8. Please locate the line writing " ' "Amount": "#CalculateFinalPrice... ' ", as depicted in the code example above with the "<<<<<<<<<<<<<<<<<<<<<<<" marks.
    The first of the two lines that the changes will occur (in our example) is this: ' "Amount": "#CalculateFinalPrice(#currentvalueatpath($.invoiceItemTaxes),#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))", '

    A quick explanation of the line: This JSON line calculates the Final Price of the generated invoice inside our BSS platform, by multiplying the "unit price" to the "quantity" and then adds at the end the tax percentage accordingly on that price. By removing the TAX entity from the calculation the BSS will no longer push the incorrect Final Price, rather it will push the Net amount along with the quantity of the products towards the Quickbooks platform.   
    Consequently, in this line, you must remove the part that has inside the parenthesis the taxation/VAT value path so that the changed line will look like this:

    New Amount line
    "Amount": "#CalculateFinalPrice(,#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",



  9. Now some lines must be added after the line with the "Amount" calculation mentioned above. The line of code that needs to be added inside the JSON was added by us so that we can push the taxation information towards the Quickbooks platform as mentioned at the beginning of the issue's explanation.

    Please locate the line writing "TaxCodeRef" and the one below it writing "value", as depicted in the exemplary code below with the "<<<<<<<<<<<<<<<<<<<<<<<" marks, provided by us.
    You will have to alter it and then copy and paste it within your BSS JSON code, but first, read the logic of the line below (#5) before continuing with the addition of the lines inside your JSON code.

    InvoiceRequest
    {
      "MetaData": {
        "CreateTime": "#valueof($.invoice.createdAt)",
        "LastUpdatedTime": "#valueof($.invoice.updatedAt)"
      },
      "TxnDate": "#valueof($.invoice.invoiceDate)",
      "Line": {
        "#loop($.invoice.invoiceItems)": {
          "Id": "#add(#currentindex(),1)",
          "Amount": "#CalculateFinalPrice(,#currentvalueatpath($.unitPrice),#currentvalueatpath($.quantity))",
          "DetailType": "#valueof($.serverVariables.invoice_Detail_Type)",
          "SalesItemLineDetail": {
            "TaxCodeRef": {														                                                     <<<<<<<<<<<<<<<<<<<<<<<
              "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='VAT 15%')].value),1,14,10)"   <<<<<<<<<<<<<<<<<<<<<<<
            },
            "ItemRef": {
              "value": "#currentvalueatpath($.product.integrationId)",
              "name": "#currentvalueatpath($.product.name)"
            },
            "UnitPrice": "#currentvalueatpath($.unitPrice)",
            "Qty": "#currentvalueatpath($.quantity)"
          }
        }
      },
      "CustomerRef": {
        "value": "#valueof($.invoice.account.integrationId)",
        "name": "#valueof($.invoice.account.name)"
      },
      "BillAddr": {
        "Line1": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address1)",
        "Line2": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].address2)",
        "City": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].city)",
        "Country": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].countryName)",
        "PostalCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].postCode)",
        "CountrySubDivisionCode": "#valueof($.invoice.billingAccount.addresses[?(@.isBilling==true)].region)"
      },
      "DueDate": "#valueof($.invoice.dueDate)",
      "TotalAmt": "#valueof($.invoice.totalAmount)",
      "CurrencyRef": {
        "value": "#valueof($.invoice.account.currency.mnemonic)",
        "name": "#valueof($.invoice.account.currency.name)"
      },
      "BillEmail": {
        "Address": "#valueof($.invoice.billingAccount.corpEmail)"
      },
      "Balance": "#valueof($.invoice.balance)"
    }


  10. The second of the two lines that the changes will occur (in our example) is this: ' "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='VAT 15%')].value),1,14,10)" '.
    A quick explanation of the line: This JSON line has an "if" statement that if True, will push the value of the account's custom field with the name " 'VAT 15%' " towards the Quickbooks platform. The value will contain for example the number 15. The last number located at the end of the line "1,14,10" have the following meaning: 

    Name
    : "VAT 15%" → The name of the account custom field corresponding to a fifteen percent (15%) VAT value.
    First Number: "1"→ Means that the "if" condition is true.
    Second Number: "14"→ Is the value that will be sent to Quickbooks as a "TaxCodeRef ID" when the "if" condition is true.
    Third Number: "10" → Is the value that will be sent to Quickbooks as a "TaxCodeRef ID" when the "if" condition is false.
    Consequently, the lines that, you must add under inside the "SalesItemLineDetail" line will look like this:

    "SalesItemLineDetail": {
            "TaxCodeRef": {														                                                     
              "value": "#ifcondition(#valueof($.invoice.account.customValues[?(@.customField.caption=='TAX 15%')].value),1,14,10)"
            },


    Lastly, after you have finished configuring the "invoiceUpdateRequest" method, please click on the "Save Transformation" button to save the changes.


  11. After you have finished configuring both methods "invoiceRequest" and "invoiceUpdateRequest", please click on the Save button located on the top of the Integration Systems page, to save the new changes inside the whole JSON file.

To recapitulate, since we can’t utilize the non-exposed field responsible for carrying the taxation information between the two platforms, we are partially changing the JSON connector to resolve the issue. The altered JSON file will from now on push the invoices with no tax but only the net amount and the details of how this net amount must be taxed will be also pushed to Quickbooks via the new custom fields which will retain the taxation rates for the customer, related to the account that is being charged. Then the Quickbooks platform gets this information and performs the calculation of the total amount (Net Amount + VAT) of a given invoice.