|
| 1 | +# API Reports - Finance |
| 2 | + |
| 3 | +Read-only API layer that exposes raw financial data (GL entries, customer/vendor |
| 4 | +ledger entries, budgets, dimensions) through OData/REST endpoints. Unlike the |
| 5 | +standard BC API v2.0 financial endpoints (trialBalance, balanceSheet, etc.) which |
| 6 | +return pre-aggregated report data, this app exposes granular transactional records |
| 7 | +that consumers aggregate themselves -- a "data warehouse" approach for building |
| 8 | +custom financial reports. |
| 9 | + |
| 10 | +## Quick reference |
| 11 | + |
| 12 | +- **ID range**: 30300--30399 |
| 13 | +- **Namespace**: Microsoft.API.FinancialManagement |
| 14 | +- **API route**: `api/microsoft/reportsFinance/beta/` |
| 15 | +- **API version**: beta (not GA -- endpoints may change) |
| 16 | + |
| 17 | +## How it works |
| 18 | + |
| 19 | +The app defines 9 API Pages and 6 API Queries, all read-only. Pages expose |
| 20 | +master/reference data (chart of accounts, customers, vendors, dimensions, |
| 21 | +budgets, accounting periods, business units, global settings). Queries expose |
| 22 | +transactional data (GL entries, GL budget entries, customer ledger entries, |
| 23 | +detailed customer ledger entries, vendor ledger entries, detailed vendor ledger |
| 24 | +entries). |
| 25 | + |
| 26 | +Every object follows the same template: `PageType = API` or `QueryType = API`, |
| 27 | +`DataAccessIntent = ReadOnly`, all insert/modify/delete disabled, `ODataKeyFields |
| 28 | += SystemId`. The app defines no tables of its own -- it reads directly from base |
| 29 | +app tables (G/L Entry, Cust. Ledger Entry, etc.). |
| 30 | + |
| 31 | +The only procedural logic lives in two page triggers: |
| 32 | + |
| 33 | +- **Accounting Periods** (`APIFinanceAccPeriods.Page.al`): computes |
| 34 | + `FiscalYearStartDate`, `FiscalYearEndDate`, and `EndingDate` on each record |
| 35 | + fetch. The ending date is derived by peeking at the next period's start date |
| 36 | + and subtracting one day. |
| 37 | + |
| 38 | +- **GL Accounts** (`APIFinanceGLAccount.Page.al`): reconstructs the chart of |
| 39 | + accounts parent-child hierarchy at runtime using a `Dictionary<Integer, |
| 40 | + Code[20]>` keyed by indentation level. This is order-dependent -- it relies on |
| 41 | + records arriving sorted by account number with ascending indentation. |
| 42 | + |
| 43 | +## Things to know |
| 44 | + |
| 45 | +- All 15 data endpoints are completely read-only. There is zero write logic, zero |
| 46 | + events, zero extensibility hooks, and zero codeunits. |
| 47 | +- The GL Account parent tracking via dictionary is fragile. It works because API |
| 48 | + pages iterate records in sort order, but the pattern wouldn't survive |
| 49 | + re-sorting or filtering that breaks indentation sequencing. |
| 50 | +- `globalSettings` is a virtual page -- it reads from both the Company record and |
| 51 | + General Ledger Setup in `OnOpenPage`, exposing just company name, LCY code, and |
| 52 | + additional reporting currency. |
| 53 | +- The app has several caption typos in the query objects: `entryType` is captioned |
| 54 | + as `'Entry Number'` in both detailed ledger entry queries, and |
| 55 | + `initialEntryGlobalDim2` is captioned as `'...Dimension 1'` instead of |
| 56 | + `'...Dimension 2'`. |
| 57 | +- The `reveresd` column name in `APIFinanceGLEntry.Query.al` is a typo for |
| 58 | + `reversed`. |
| 59 | +- GL Budget Entry query has a duplicate column: both `accountNo` and |
| 60 | + `generalLedgerAccountNumber` map to the same `G/L Account No.` field. |
| 61 | +- Permissions follow the standard stacking pattern: one base permission set |
| 62 | + (`API Reports Finance - Objects`) extended into 6 D365 roles. |
0 commit comments