# Netsuite integration mapping

### Connection to NetSuite

Follow these steps to connect Fincome to NetSuite:

1. Make sure your NetSuite account is enabled for REST Web Services and has the appropriate role/permissions.
2. Obtain the following credentials from your NetSuite account or your integration record:
   * Account ID (replace `_` with `-` in the URLs)
   * Client ID

> Note: The connector currently implements a Machine-to-Machine flow (client\_credentials / JWT). Interactive OAuth flows are present in the code but not yet implemented. OAuth will be the main method for NetSuite WebServices.

***

### Synchronized data

| **NetSuite object**                       | **Synchronized key fields**                                                                                                                                          |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Customers                                 | id, entityId (name), email                                                                                                                                           |
| Invoices (transaction + lines + currency) | invoice\_id, invoice\_number, customer\_id, date, status, invoice\_line\_item\_id, description, netamount, foreignamount, currency\_code, period\_start, period\_end |
| Currency                                  | symbol → currency\_code                                                                                                                                              |

***

### Detailed integration behavior

* **SuiteQL extraction**\
  The connector composes SuiteQL queries combining the objects `transaction`, `transactionLine` and `currency`. The selected fields are hard-coded for now, but could become configurable in the future.
* **Incremental extraction**

  The NetSuite integration supports incremental extraction via the field `last_modified_date`.
* **Authentication & token refresh**
  * Access tokens expire after one hour and are refreshed automatically.
* **Line type classification**
  * The NetSuite connector determines if a line is `subscription` or `one_off` based on the custom field `custcol_iw_item_revenue_category` and the validity of the period dates.
* **Currency handling**
  * The connector retrieves `currency.symbol` as `currency_code`.
  * If `netamount` and `foreignamount` both exist, the latter can be used to calculate original currency or base currency amounts as needed.

***

### Things to know

* **Custom fields used**\
  The connector uses NetSuite custom fields (e.g. `custcol_iw_rr_start_date`, `custcol_iw_rr_end_date`, `custcol_iw_item_revenue_category`). If your NetSuite account uses other IDs, update `fields_per_object`, `where_conditions` and the mapping logic accordingly.
* **Date formats**\
  The connector expects `DD/MM/YYYY`. Adjust the OperationMap `Date` if NetSuite returns a different format.
* **Pagination and offsets**\
  SuiteQL supports `limit` and `offset`. Large historical synchronizations can take time; the connector updates the cursor and resumes automatically.
* **Scope & permissions**\
  The integration requires the scope `rest_webservices` and an account/role with read access to `transaction`, `transactionLine`, `currency` and customer data.

***

### Integration overview

| **Item**               | **Detail**                                                    |
| ---------------------- | ------------------------------------------------------------- |
| Integration method     | JWT client-assertion → OAuth2 token (Machine-to-Machine)      |
| Supported objects      | customer, transaction (invoice), transactionLine, currency    |
| Sync frequency         | Incremental via cursor + on-demand token refresh              |
| Initial import         | Full history via SuiteQL with offset pagination               |
| Synchronization method | SuiteQL queries via NetSuite REST `query/v1/suiteql` endpoint |
| Deletions              | Not propagated (soft-deletes must be handled separately)      |

### Data settings & behaviors

| **Parameter**               | **Behavior**                                                                             |
| --------------------------- | ---------------------------------------------------------------------------------------- |
| Date format                 | `%d/%m/%Y` via the OperationMap `Date`                                                   |
| Invoice status mapping      | `A` → open, `B` → paid, `D` → pending, others ignored                                    |
| Invoice line classification | `custcol_iw_item_revenue_category` + period dates                                        |
| Amounts inversion           | `netamount` currently inverted in `IliAmount`                                            |
| Filter                      | Invoices with `custcol_iw_item_revenue_category IS NOT NULL` and `netamount IS NOT NULL` |

### Technical mapping (NetSuite → Fincome)

#### Customers

| **NetSuite** | **Fincome**  |
| ------------ | ------------ |
| id           | original\_id |
| entityId     | name         |
| email        | email        |

#### Invoices & Lines

| **NetSuite**                    | **Fincome**                                                  |
| ------------------------------- | ------------------------------------------------------------ |
| t.id                            | original\_id (invoice)                                       |
| t.number                        | invoice\_number                                              |
| t.entity                        | customer\_id                                                 |
| t.tranDate                      | date                                                         |
| t.status                        | status (via `InvoiceStatus`)                                 |
| tl.id                           | original\_id (invoice line)                                  |
| tl.item                         | product / SKU                                                |
| tl.netamount                    | amount\_excluding\_tax\_after\_discount (currently inverted) |
| tl.foreignamount                | optional foreign amount                                      |
| tl.memo                         | description                                                  |
| tl.custcol\_iw\_rr\_start\_date | period\_start                                                |
| tl.custcol\_iw\_rr\_end\_date   | period\_end                                                  |
| cur.symbol                      | currency\_code                                               |

#### Credit Notes

| **NetSuite**                              | **Fincome**                     |
| ----------------------------------------- | ------------------------------- |
| transaction with recordtype = credit note | original\_id (credit note)      |
| linked invoice                            | invoice\_id                     |
| line id                                   | original\_id (credit note line) |
| netamount                                 | amount (negative)               |
| foreignamount                             | optional foreign amount         |
| memo                                      | description                     |
| start/end dates                           | period\_start / period\_end     |
| currency.symbol                           | currency\_code                  |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fincome.gitbook.io/help-center/en/resources/integration-mapping-and-api/netsuite-integration-mapping.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
