-
Notifications
You must be signed in to change notification settings - Fork 9
OL-7 NestedLoops Example #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Creating a Loop Step Within Another Loop Step | ||
|
|
||
| ## Problem this solves: | ||
| * "How should I setup a loopstep from within another loop and aggragate data from the nested loop?" | ||
|
|
||
| ## Solution: | ||
| You will need to call the primary loop as the on failure branch of the nested loop. You will then need top use the standard aggregator approach to maintain the data from the nested loop. This approach is outlined below: | ||
|
|
||
| ``` | ||
| let arr = steps.aggregator ? steps.aggregator.arr : []; | ||
|
|
||
| <insert custom logic> | ||
|
|
||
| done({arr:arr}) | ||
| ``` | ||
|
|
||
| This will look to see if the step has already run and if it has it will get the results from the step and you can add to them or if it has not run it will start with an empty array. | ||
|
|
||
| Included in this folder is [nestedLoops.json](nestedLoops.json), which is a formula json that can be imported and used to test with. With only a handful of steps, this formula will get invoices (from an Element Instance), loop through all those invoices and then through each invoice's line items, retrieve the line item's amount, and add it to an array. After is has finished looping through it will log an array of all of the line items' amount. This formula uses a manual trigger for easy testing. | ||
|
|
||
| ## IMPORTANT NOTES: | ||
| * You will need an authenticated Element instance with a GET /invoices API (endpoint). Additionally, the invoices in the response will also need to have line items so that we could loop through those as well. This formula was built using Quickbooks Online as their inovice records have a line items array. You can authenticate one in the UI. | ||
| * Your Element needs to return an array of line items that each contain a field called **Amount**. Alternatively, you can update the javascript step called `aggregator` to refer to a field that exists on the API you choose (i.e. for Zoho CRM v2, the field **Full_Name** could be used instead). You can update this step easily in the Formula UI. | ||
| * There is no paging in this formula. Additionally there is a pagination query in place to limit the number of invoices that get returned to 20. This extra step was added to make testing slightly easier as there are only a handful of records to work with. Please be mindful of this deliberate limitation as you test. | ||
|
|
||
| ## Import Using the UI: | ||
| 1. Go to the Formulas UI and click the `BUILD NEW FORMULA` button, then select `Import` from the dropdown. | ||
| 2. Find the json file `nestedLoops.json` in the nestedLLoops directory and use it to import the formula. | ||
| 3. You can now interact with the formula in the UI. You can update the `aggregator` step as needed. Use the `TRY IT OUT` button to select (and/or create) a formula instance, as well as the Element instance (Finance System) you want to use. Then run the formula. | ||
|
|
||
| ## Import Using the doctor: | ||
| 1. Insure you have the latest non-beta version of the doctor installed via npm. You can follow the directions found [here](https://www.npmjs.com/package/ce-util) or run the command `npm install -g ce-util`. You'll need a version of node that is >= v6.3.0. You will need to upload the file from TheDoctor directory, as files uploaded with the doctor have a different structure than files imported via UI. | ||
| 2. From the TheDoctor directory, run the command: | ||
| ``` | ||
| doctor upload formulas <acctNickName> -f nestedLoops.json | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RickyAmparoCloud It likes like you've called the formula "formula.json" in the doctor folder. I think you'll either have to rename it or change this line to refer to "formula.json" instead of "nestedLoops.json". |
||
| ``` | ||
| This will upload the Nested Loops Formula into the specified account. | ||
|
|
||
| 3. You can now interact with the formula in the UI. You can update the `aggregator` step as needed. Use the `TRY IT OUT` button to select (and/or create) a formula instance, as well as the Element instance (Finance System) you want to use. Then run the formula. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| let arr = steps.aggregator ? steps.aggregator.arr : []; | ||
|
|
||
| arr.push(steps.loopThroughInvoiceLines.entry.amount) | ||
|
|
||
| done({ | ||
| arr: arr | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RickyAmparoCloud @nick-bair I'll let Nick confirm but I want to say you don't need "arr:arr" inside of the done callback. Instead you can just pass in done ({ arr });
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's correct. |
||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| { | ||
| "active": true, | ||
| "configuration": [ | ||
| { | ||
| "description": "This is the QBO element that you will be retrieving invoices from. ", | ||
| "key": "QBOInstance", | ||
| "name": "QBOInstance", | ||
| "required": true, | ||
| "type": "elementInstance" | ||
| } | ||
| ], | ||
| "debugLoggingEnabled": false, | ||
| "debugLoggingExpires": "2020-11-14T02:55:23Z", | ||
| "engine": "v3", | ||
| "id": 41889, | ||
| "name": "nestedLoops", | ||
| "singleThreaded": false, | ||
| "steps": [ | ||
| { | ||
| "name": "makePaginationQuery", | ||
| "onFailure": [], | ||
| "onSuccess": [ | ||
| "getInvoices" | ||
| ], | ||
| "properties": {}, | ||
| "type": "script" | ||
| }, | ||
| { | ||
| "name": "getInvoices", | ||
| "onFailure": [], | ||
| "onSuccess": [ | ||
| "loopThroughInvoices" | ||
| ], | ||
| "properties": { | ||
| "api": "/invoices", | ||
| "elementInstanceId": "${config.QBOInstance}", | ||
| "method": "GET", | ||
| "query": "${steps.makePaginationQuery.pagination}" | ||
| }, | ||
| "type": "elementRequest" | ||
| }, | ||
| { | ||
| "name": "loopThroughInvoices", | ||
| "onFailure": [ | ||
| "gracefulExit" | ||
| ], | ||
| "onSuccess": [ | ||
| "loopThroughInvoiceLines" | ||
| ], | ||
| "properties": { | ||
| "list": "${steps.getInvoices.response.body}" | ||
| }, | ||
| "type": "loop" | ||
| }, | ||
| { | ||
| "name": "loopThroughInvoiceLines", | ||
| "onFailure": [ | ||
| "loopThroughInvoices" | ||
| ], | ||
| "onSuccess": [ | ||
| "aggregator" | ||
| ], | ||
| "properties": { | ||
| "list": "${steps.loopThroughInvoices.entry.line}" | ||
| }, | ||
| "type": "loop" | ||
| }, | ||
| { | ||
| "name": "aggregator", | ||
| "onFailure": [], | ||
| "onSuccess": [ | ||
| "loopThroughInvoiceLines" | ||
| ], | ||
| "properties": {}, | ||
| "type": "script" | ||
| }, | ||
| { | ||
| "name": "gracefulExit", | ||
| "onFailure": [], | ||
| "onSuccess": [], | ||
| "properties": {}, | ||
| "type": "script" | ||
| } | ||
| ], | ||
| "triggers": [ | ||
| { | ||
| "async": true, | ||
| "name": "trigger", | ||
| "onFailure": [], | ||
| "onSuccess": [ | ||
| "makePaginationQuery" | ||
| ], | ||
| "properties": {}, | ||
| "type": "manual" | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| done(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| let pageInfo = {"pageSize": 3} | ||
|
|
||
| done({"pagination":pageInfo}) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RickyAmparoCloud Not sure it matters much, but I think you can pass in done({ pageInfo }) and just refer to .pageInfo.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It depends how you pass it to done: done({ pageInfo }) => access later by calling stepName.pageInfo |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {"id":41889,"name":"nestedLoops","debugLoggingExpires":"2020-11-14T02:55:23Z","userId":8584,"accountId":7612,"createdDate":"2020-11-13T18:46:20Z","steps":[{"id":445708,"onSuccess":["loopThroughInvoiceLines"],"onFailure":[],"name":"aggregator","type":"script","properties":{"body":"let arr = steps.aggregator ? steps.aggregator.arr : [];\n\narr.push(steps.loopThroughInvoiceLines.entry.amount)\n\ndone({\n arr: arr\n})"}},{"id":445684,"onSuccess":["loopThroughInvoices"],"onFailure":[],"name":"getInvoices","type":"elementRequest","properties":{"api":"/invoices","query":"${steps.makePaginationQuery.pagination}","method":"GET","elementInstanceId":"${config.QBOInstance}"}},{"id":445709,"onSuccess":[],"onFailure":[],"name":"gracefulExit","type":"script","properties":{"body":"done();"}},{"id":445710,"onSuccess":["aggregator"],"onFailure":["loopThroughInvoices"],"name":"loopThroughInvoiceLines","type":"loop","properties":{"list":"${steps.loopThroughInvoices.entry.line}"}},{"id":445707,"onSuccess":["loopThroughInvoiceLines"],"onFailure":["gracefulExit"],"name":"loopThroughInvoices","type":"loop","properties":{"list":"${steps.getInvoices.response.body}"}},{"id":445685,"onSuccess":["getInvoices"],"onFailure":[],"name":"makePaginationQuery","type":"script","properties":{"body":"let pageInfo = {\"pageSize\": 3}\n\ndone({\"pagination\":pageInfo})"}}],"triggers":[{"id":38003,"onSuccess":["makePaginationQuery"],"onFailure":[],"type":"manual","async":true,"name":"trigger","properties":{}}],"engine":"v3","active":true,"singleThreaded":false,"debugLoggingEnabled":false,"configuration":[{"id":82541,"key":"QBOInstance","name":"QBOInstance","type":"elementInstance","description":"This is the QBO element that you will be retrieving invoices from. ","required":true}]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RickyAmparoCloud "top" should be "to" ;)