Netsuite model

Profit and loss by month

NetSuite's Income Statement by month and account, built from the general ledger.

Grain
accounting book x subsidiary x month x account, income statement account types only, months with postings only
Built from
  1. 6
    Raw tables
  2. 6
    Staging
  3. 2
    Core
  4. 1
    Analytics
Reads from Netsuite
accountaccounttypedeletedrecordtransactiontransactionaccountinglinetransactionline
Ships as
Weld and dbt SQL, open source on GitHub
core.netsuite.profit_and_loss_by_month
1-- core.netsuite.profit_and_loss_by_month
2-- NetSuite's Income Statement by month and account, built from the general
3-- ledger.
4--
5-- Grain: accounting book x subsidiary x month x account, income statement account
6-- types only, months with postings only.
7--
8-- Currency: the subsidiary's base currency. Keep subsidiary_id in the grain of
9-- any rollup, or translate to one currency first.
10--
11-- Signs:
12--   amount            as the report prints it: income positive on income accounts,
13--                     expenses positive on expense accounts
14--   net_income_impact credit - debit: income positive, expenses negative. A plain
15--                     SUM over rows is their contribution to net income, so Gross
16--                     Profit is the sum over the Income and Cost of Goods Sold
17--                     sections and Net Income the sum over everything.
18--
19-- Months are calendar months of the transaction date; see trial_balance.sql for
20-- how that differs from NetSuite's posting periods.
21
22SELECT
23    netsuite_account,
24    accounting_book_id,
25    subsidiary_id,
26    transaction_month                      AS month,
27    account_id,
28    ANY_VALUE(account_number)              AS account_number,
29    ANY_VALUE(account_name)                AS account_name,
30    ANY_VALUE(account_type_id)             AS account_type_id,
31    ANY_VALUE(account_type_name)           AS account_type_name,
32    CASE ANY_VALUE(account_type_id)
33        WHEN 'Income'     THEN 'Income'
34        WHEN 'COGS'       THEN 'Cost of Goods Sold'
35        WHEN 'Expense'    THEN 'Expenses'
36        WHEN 'OthIncome'  THEN 'Other Income'
37        WHEN 'OthExpense' THEN 'Other Expenses'
38        ELSE 'Other'
39    END                                    AS section,
40    CASE ANY_VALUE(account_type_id)

This model and the 8 it depends on. Deploy them together; refs like {{staging.…}} resolve to the matching folders in Weld, and the dbt view uses source() and ref().

Notes

How it counts. And where it stops.

Currency: the subsidiary's base currency. Keep subsidiary_id in the grain of any rollup, or translate to one currency first. Signs: amount as the report prints it: income positive on income accounts, expenses positive on expense accounts net_income_impact credit - debit: income positive, expenses negative. A plain SUM over rows is their contribution to net income, so Gross Profit is the sum over the Income and Cost of Goods Sold sections and Net Income the sum over everything. Months are calendar months of the transaction date; see trial_balance.sql for how that differs from NetSuite's posting periods.

Raw tables it reads

  • raw.netsuite.account
  • raw.netsuite.accounttype
  • raw.netsuite.deletedrecord
  • raw.netsuite.transaction
  • raw.netsuite.transactionaccountingline
  • raw.netsuite.transactionline

Put Netsuite in front
of your agents.

Connect Netsuite, deploy the models, and ask questions in Claude, Cursor or ChatGPT. Free for 14 days, no credit card.