{
  "id": "iRaDuebfCVnNBqF1",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Sync NetSuite Customers to Salesforce Accounts and Contacts",
  "tags": [],
  "nodes": [
    {
      "id": "517d49d4-bfb1-427e-98b2-1e45965c5311",
      "name": "Is Company?",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b551567c-df5c-4d02-86a0-82752d35df2b",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.isPerson }}",
              "rightValue": "false"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "14529f4d-5bb7-492b-aefd-195d2541e002",
      "name": "NS: Customer - Get record",
      "type": "n8n-nodes-netsuite-rest.netSuiteRest",
      "position": [
        672,
        -160
      ],
      "parameters": {
        "id": "={{ $json.id }}",
        "resource": "Customer",
        "operation": "get /customer/{id}",
        "additionalFields": {}
      },
      "credentials": {
        "netSuiteRestOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "709bf40e-3ac7-4108-8683-5e91564bf05d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        -544
      ],
      "parameters": {
        "width": 460,
        "height": 960,
        "content": "### This n8n template demonstrates how to export NetSuite Customers and Upsert into Salesforce.\n\n### How it works\n* Workflow processes 20 records per iteration until there are no records left.\n* To find unique records - NetSuite Internal Id is used in Salesforce as External Id.\n* If record in NetSuite is a company - it is created/updated as Salesforce Account.\n* If record in NetSuite is an individual - it is created/updated as Salesforce Account and Salesforce Contact (with Account as parent record).\n\n\n### How to use\n* Set up NetSuite and Salesforce connections.\n* The 'Execute Workflow Daily' node is used as an example but feel free to replace it with any other trigger.\n* Run the flow manually to process all records. Non-existing records will be created, all existing - updated.\n* After running workflow manually - you can set up schedule to run the flow. To process only records updated after last workflow run date - switch 'NS: Customer - Get All records' node with 'NS: Customer - Get Delta records'\n\n\n### Requirements\n* Salesforce connection working and External Id field exists.\n* NetSuite connection working. Please refer to the details provided in [NetSuite REST Node description](https://www.npmjs.com/package/n8n-nodes-netsuite-rest).\n\n### Note\n* When running a workflow with Schedule trigger - on a first run workflow will use {today} date as a last export date.\n* Currently workflow uses NetSuite REST community node   and can run on self-hosted n8n instance only.\n\n### Need Help?\nFeel free to reach out to support@entechsolutions.com\n\nHappy Integrating!"
      },
      "typeVersion": 1
    },
    {
      "id": "79637b70-9586-473b-a053-fc54bcf931c5",
      "name": "SF: Create or Update Company Account",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1552,
        -256
      ],
      "parameters": {
        "name": "={{ $json.companyName }}",
        "resource": "account",
        "operation": "upsert",
        "externalId": "External_ID__c",
        "externalIdValue": "={{ $json.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": false,
      "typeVersion": 1
    },
    {
      "id": "03827337-fcd9-4c53-a427-0b65d21fce57",
      "name": "SF: Create or Update Contact",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1664,
        -48
      ],
      "parameters": {
        "lastname": "={{ $('Is Company?').item.json.lastName }}",
        "resource": "contact",
        "operation": "upsert",
        "externalId": "External_ID__c",
        "externalIdValue": "={{ $json.id }}",
        "additionalFields": {
          "email": "={{ $('Is Company?').item.json.email }}",
          "firstName": "={{ $('Is Company?').item.json.firstName }}",
          "acconuntId": "={{ $json.id }}"
        }
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": false,
      "typeVersion": 1
    },
    {
      "id": "21e2e2f6-f9e6-4c66-a6a0-33cc5c8aa4c8",
      "name": "SF: Create or Update Person's Account",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        1440,
        -48
      ],
      "parameters": {
        "name": "={{ $json.firstName + ' ' + $json.lastName}}",
        "resource": "account",
        "operation": "upsert",
        "externalId": "External_ID__c",
        "externalIdValue": "={{ $json.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "retryOnFail": false,
      "typeVersion": 1
    },
    {
      "id": "3e3b7363-ac9b-44f1-900b-d493a9db597e",
      "name": "Split Customers Array",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        448,
        -160
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "items"
      },
      "typeVersion": 1
    },
    {
      "id": "b4e45f33-2385-472d-b619-b45b3bbad8c8",
      "name": "Merge Company/Contact Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        2048,
        -144
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "a88430cf-850b-4ee7-bda3-035d65f160bf",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1312,
        -416
      ],
      "parameters": {
        "color": 5,
        "width": 592,
        "height": 560,
        "content": "## Salesforce section\n\n### Records are inserted/updated into Salesforce here"
      },
      "typeVersion": 1
    },
    {
      "id": "e4accef6-6a08-4a36-8100-32e831bffd59",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -416
      ],
      "parameters": {
        "color": 7,
        "width": 784,
        "height": 496,
        "content": "## Netsuite section\n\n### Records are pulled from NetSuite here\n\n### Fell free to use filter with Q parameter passed in 'NS: Customer - Get records' step\nFor example - email START_WITH barbara\n\nRead about using Q parameter in [NetSuite Docs](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1545222128.html)"
      },
      "typeVersion": 1
    },
    {
      "id": "19070186-030e-44bb-a9ff-8b5a474cee3f",
      "name": "Workflow is finished",
      "type": "n8n-nodes-base.noOp",
      "position": [
        256,
        368
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "7102959c-8f8b-4cd7-bfda-c33b150156ea",
      "name": "Has More Records?",
      "type": "n8n-nodes-base.if",
      "position": [
        -320,
        -96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "da799032-1cc2-421d-91cd-4eb174744162",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.hasMore }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7a88c79c-142b-47c1-b690-1b7ea4d30db8",
      "name": "Retrieve Paging Offset and LastExportDate",
      "type": "n8n-nodes-base.code",
      "position": [
        -96,
        -160
      ],
      "parameters": {
        "jsCode": "const workflowStaticData = $getWorkflowStaticData('global');\nconst lastExportDate = workflowStaticData.lastExportDate ? workflowStaticData.lastExportDate : $today.minus({days: 1}).toFormat('MM/dd/yyyy')\n\nreturn [\n  {\n      offset: workflowStaticData.offset,\n      lastExportDate: lastExportDate\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "3eaa9173-d196-400f-853c-49f4a7f13847",
      "name": "Update Paging Offset and LastExportDate",
      "type": "n8n-nodes-base.code",
      "position": [
        2272,
        -80
      ],
      "parameters": {
        "jsCode": "const workflowStaticData = $getWorkflowStaticData('global');\n\nworkflowStaticData.offset = workflowStaticData.offset+20\nworkflowStaticData.hasMore = $('NS: Customer - Get All records').isExecuted ? $('NS: Customer - Get All records').first().json.hasMore: $('NS: Customer - Get Delta records').first().json.hasMore\n\nreturn [\n  {\n      offset: workflowStaticData.offset,\n      hasMore: workflowStaticData.hasMore\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "fe7f6315-dcba-4e31-ad10-cf8856633b6a",
      "name": "Execute Workflow Daily",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -768,
        -96
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "66e23779-e65f-4659-905f-c931167b8b0d",
      "name": "Init Offset",
      "type": "n8n-nodes-base.code",
      "position": [
        -544,
        -96
      ],
      "parameters": {
        "jsCode": "// initialize staticData object\nconst workflowStaticData = $getWorkflowStaticData('global');\n\nworkflowStaticData.offset = 0\nworkflowStaticData.hasMore = true\n\nreturn [\n  {\n      offset: workflowStaticData.offset,\n      hasMore: workflowStaticData.hasMore\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "d85c4562-19c4-4eaa-8486-207332facfe1",
      "name": "NS: Customer - Get Delta records",
      "type": "n8n-nodes-netsuite-rest.netSuiteRest",
      "position": [
        224,
        -656
      ],
      "parameters": {
        "resource": "Customer",
        "isDebugMode": true,
        "additionalFields": {
          "q": "=lastModifiedDate ON_OR_AFTER \"{{ $json.lastExportDate }}\"",
          "limit": 20,
          "offset": "={{ $json.offset }}"
        }
      },
      "credentials": {
        "netSuiteRestOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a42909a2-1cfd-49fe-8461-e42f665e744f",
      "name": "NS: Customer - Get All records",
      "type": "n8n-nodes-netsuite-rest.netSuiteRest",
      "position": [
        208,
        -160
      ],
      "parameters": {
        "resource": "Customer",
        "isDebugMode": true,
        "additionalFields": {
          "limit": 20,
          "offset": "={{ $json.offset }}"
        }
      },
      "credentials": {
        "netSuiteRestOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e8b078e6-099c-46e7-ae9d-5400d8355614",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -912
      ],
      "parameters": {
        "width": 368,
        "height": 480,
        "content": "## Run for Delta records\n\n### Replace a 'NS: Customer - Get All records' node with a node below to run flow only for records changed after Last Workflow Run"
      },
      "typeVersion": 1
    },
    {
      "id": "9cd4dfd7-b24b-4752-84d3-cb44ba02078e",
      "name": "Update LastExportDate",
      "type": "n8n-nodes-base.code",
      "position": [
        48,
        368
      ],
      "parameters": {
        "jsCode": "const workflowStaticData = $getWorkflowStaticData('global');\n\nworkflowStaticData.lastExportDate = DateTime.now().toFormat('MM/dd/yyyy')\n\nreturn [\n  {\n      lastExportDate: workflowStaticData.lastExportDate\n  }\n];"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d2eda63c-ab7d-4564-bf5d-084e70e37146",
  "connections": {
    "Init Offset": {
      "main": [
        [
          {
            "node": "Has More Records?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Company?": {
      "main": [
        [
          {
            "node": "SF: Create or Update Company Account",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SF: Create or Update Person's Account",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has More Records?": {
      "main": [
        [
          {
            "node": "Retrieve Paging Offset and LastExportDate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update LastExportDate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Customers Array": {
      "main": [
        [
          {
            "node": "NS: Customer - Get record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update LastExportDate": {
      "main": [
        [
          {
            "node": "Workflow is finished",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow Daily": {
      "main": [
        [
          {
            "node": "Init Offset",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "NS: Customer - Get record": {
      "main": [
        [
          {
            "node": "Is Company?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SF: Create or Update Contact": {
      "main": [
        [
          {
            "node": "Merge Company/Contact Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Company/Contact Results": {
      "main": [
        [
          {
            "node": "Update Paging Offset and LastExportDate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "NS: Customer - Get All records": {
      "main": [
        [
          {
            "node": "Split Customers Array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "NS: Customer - Get Delta records": {
      "main": [
        []
      ]
    },
    "SF: Create or Update Company Account": {
      "main": [
        [
          {
            "node": "Merge Company/Contact Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SF: Create or Update Person's Account": {
      "main": [
        [
          {
            "node": "SF: Create or Update Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Paging Offset and LastExportDate": {
      "main": [
        [
          {
            "node": "Has More Records?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve Paging Offset and LastExportDate": {
      "main": [
        [
          {
            "node": "NS: Customer - Get All records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}