# 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                  |
