Fixed Asset
The register of a company’s capitalised assets — what it cost, who holds it and where, how it depreciates and which GL codes the depreciation posts to. Assets are entered by hand on the Asset Register screen, or by CSV import. It is not a document applet: it writes its journals directly, every one posted the moment it is written, and every acquisition, disposal and depreciation run lands in Ledger and Journal. Nothing depreciates on its own — each month is a run somebody has to trigger, and a month nobody runs is simply not depreciated — and the run’s journal is not yet usable (see the note below), so plan to post depreciation as a journal.
Your job, and the screen for it
| The job | Screen or tab | Read |
|---|---|---|
| Register an asset | Asset Register › create (one Details tab; depreciation is set after the first save) | Asset Register |
| Record an asset bought on a purchase invoice — finalising the invoice creates no asset | Asset Register, then the asset’s Transactions tab | Asset creation from a purchase invoice |
| Record its acquisition, disposal and gain or loss — each posts its journal at once; press Save on the asset after an acquisition, and read the disposal warning first | Edit asset, Transactions tab | Transactions tab; What creates a journal |
| Set how it depreciates — a month with no schedule row is skipped | Edit asset, Depreciation › Configuration and Schedule | Depreciation → Configuration |
| Depreciate a month — nothing runs on its own, and until the run’s journal is fixed, post depreciation as a journal in Ledger and Journal | Depreciation Run › the run › Lines › + › RUN | The depreciation run, step by step; The depreciation journal |
| Load assets from a file | Import Fixed Asset | Import Fixed Asset (CSV columns) |
Overview
The Fixed Asset applet keeps the register of a tenant’s capitalised assets — what was bought, which company, branch and location holds it, which employee is responsible for it, what it cost, how it depreciates and which GL codes its depreciation posts to. It is opened by the finance team that owns the fixed-asset ledger, usually after a purchase invoice has been finalised.
It is not a document applet. It has no document type, no FINAL status and no numbering series.
It keeps its own records — assets, their depreciation configuration and schedule, depreciation runs,
categories, attachments and imports — and writes journals directly.
Assets reach the register by hand on the Asset Register screen or through the Import Fixed Asset CSV screen. The backend can also convert a finalised Purchase Invoice (Internal) line whose item is flagged as a fixed-asset item, but nothing starts that conversion today: no screen offers it, and it is not connected to the purchase invoice’s finalise in BigLedger’s product configuration — see Asset creation from a purchase invoice.
DEPRECIATED and posts nothing — see
The stop condition, and the status flip and
The depreciation journal. Record each month’s depreciation as a journal
in Ledger and Journal, and keep the register for the
asset, its schedule and its acquisition and disposal journals. BigLedger is tracking this.What it will not do. It will not depreciate on a schedule — every month is a run somebody opens and presses RUN on, and a month nobody runs is simply not depreciated. It will not generate a depreciation schedule: the months an asset is eligible for are added one at a time by hand. It will not inherit depreciation settings from the asset’s category. It will not revalue, impair, transfer between companies, or reverse accumulated depreciation when an asset is disposed of. And the depreciation run has enough sharp edges — set out under Lifecycle and effects — that a first month should be run on a copy of the data and reconciled line by line in Ledger and Journal before it is trusted with a period close.
Where it fits
| Direction | What | Why |
|---|---|---|
| Upstream | Purchase Invoice (Internal) | The backend can convert a line whose item is a fixed-asset item into a DRAFT asset record — but nothing starts that conversion today (see below) |
| Upstream | Inventory Item Maintenance | The item’s property_json carries the type and category_guid copied onto the converted asset |
| Upstream | Chart of Account | Supplies the asset GL code, the depreciation-expense GL code and the accumulated-depreciation GL code |
| Upstream | Organization | Company, branch and location; the company’s FIXED_ASSET_REGISTER default GL link used by the purchase conversion |
| Upstream | Employee | The person-in-charge drop-down reads entity headers |
| Downstream | Ledger and Journal | Every acquisition, adjustment, disposal, other journal and depreciation line lands here as a journal |
| Downstream | Financial Report | Depreciation expense and accumulated depreciation reach the P&L and balance sheet through the ledger |
Screens and menus
The applet mounts at applet/tnt/wavelet/erp/asset-register-applet and its sidebar has five entries.
| Menu | Route | What it shows |
|---|---|---|
| Asset Register | asset-register | The asset listing, plus create and edit |
| Asset Category | asset-category | The category master |
| Depreciation Run | depreciation-run | Monthly run headers and their result lines |
| Reports | reports | The fixed-asset report with PDF and XLS export |
| Import Fixed Asset | file-import | CSV upload and the per-row staging grid |
Asset Register
The listing columns are Asset Code, Asset Name, Category, Company, Location, Purchase Date, Purchase Price, Depreciation Method and Asset Status. It is an ag-Grid server-side grid with an advanced-search panel over company, branch, location, purchase-date range and asset-code range.

The create screen has a single Details tab. Two further tabs — Depreciation (Configuration and Schedule) and Transactions — exist in the template but are commented out, so depreciation cannot be configured until after the asset has been created.

The edit screen has six tabs — Details, Transactions, Depreciation (with Configuration and Schedule sub-tabs), Attachment, Related Doc and Other Journal — and their order is controlled by the Default Selection setting (see Configuration).
Two of them carry more weight than their names suggest. Transactions is the only screen on which an asset’s purchase price, disposal price and gain or loss are ever decided, and every row added there posts a journal straight to the ledger — there is no draft and no approval step. Depreciation → Schedule is not a generated plan: it is a hand-kept list of the individual months this asset is allowed to depreciate in, added one month at a time, and a month with no row here is a month the depreciation run will not touch.
There is no delete button on the edit screen — the markup is commented out.


The Add Depreciation panel adds one month at a time: it takes a single month/year and adds one schedule row with that month’s first and last day. There is no “generate the whole schedule” action.


Asset Category

Categories carry a code, a name, a description and a status of ACTIVE or INACTIVE. Code, name
and status are required. A category groups assets on the register listing and on the report, and
that is all it does — it carries no depreciation defaults that an asset inherits.
The platform does have a category-level depreciation configuration — a method, an averaging method, a
rate, a useful life, a residual value and both depreciation GL codes, reachable through the API with
its own permission family (API_TNT_DM_FA_CATEGORY_DEPRECIATION_CONFIG_*) — but nothing in the
fixed-asset path uses it: the depreciation run uses the per-asset configuration only, and no screen
reads or writes the category’s. Configure depreciation on each asset.
Depreciation Run

A run header holds only Company (required), Branch (optional) and a month/year picker. Opening a run
shows a read-only Main tab and a Lines tab; the + button on the Lines tab opens the
Registered Assets listing, and the RUN button lives there — not on the run header. That is the
only place the run is triggered from.
Import Fixed Asset

Columns are File Name, File Size, Format, Status, Process Status, User Error Message, Created Date and Updated Date. A blank template can be downloaded from the screen.
Reports

The report is a grouped ag-Grid (Company → Category Code) over Asset Code, Asset Name, Asset Status, Depreciation Method, Averaging Method, Purchase Date, Disposal Date, Useful Life, Purchase Price, Residual Value, Depreciation Month, Depreciation Year and Depreciation Amount, with PDF and XLS export.
The screen sends only two things — a company (it refuses to search without one, with “Please select the company”) and a month range. The search panel also offers Category and Asset Status, but the screen never sends them, so choosing either changes nothing. What it does with the two it sends is not obvious from the result:
- An asset that has never been through a depreciation run does not appear at all. The report filters on the run’s month and year, so an asset with no run is left out. Together with the configuration and the schedule it also requires, an asset needs a configuration, a schedule row and a completed run inside the range before the report will show it. The report is a record of depreciation that happened, not a register of assets.
- Rows multiply. The run-line join is on the asset alone, with no month condition, so each asset contributes one row per (schedule month × run line) pair inside the range. The Depreciation Amount column is filled only where the run month equals the schedule month; every other row of the pair carries a blank amount. Twelve months of schedule and twelve runs means 144 rows for that asset, twelve of them with a number.
- The endpoint behind the screen (
POST fa/fixed-asset-registers/reports) accepts more filters than the screen sends — branch, category, depreciation method, averaging method, asset status and a keyword. Two of them, depreciation method and averaging method, name columns that do not exist on the configuration table (depreciation_methodandaveraging_method, where the columns aredepr_methodanddepr_ave_method), so a request that sets either fails in the database. The rest — and the month range itself — are built inside a conditional on the company list, so a request with no company applies none of them and returns every asset for every month.
Configuration
Before you can use it
| Prerequisite | Where it is set | Why it matters here |
|---|---|---|
| A chart of accounts with an asset GL code, a depreciation-expense GL code and an accumulated-depreciation GL code | Chart of Account | All three drop-downs are filtered by the company’s chart of accounts; the GL code is required on the edit screen and both depreciation GL codes are required on the Configuration sub-tab |
| Company, branch and location | Organization | Company, Branch and Location are required on the asset form |
A company FIXED_ASSET_REGISTER default GL link | Organization → Company | The only company default GL link this applet ever reads, and only the purchase-invoice conversion reads it — which nothing starts today. Nothing else here needs it: the screens post to the GL codes on the asset and the codes you pick |
A primary ledger for the company (obj_type = 'PRM') | Chart of Account | Every journal this applet writes is stamped with it; the depreciation processor and the journal endpoint both look it up by company |
| At least one asset category | This applet → Asset Category | Category is required on the asset form |
| Employee entities | Employee | Only needed if you want a person-in-charge on the asset |
Applet settings
The applet has its own settings screens. They are tenant-wide, not per user — see How settings are stored and who they apply to.
One setting in this applet does anything at all.
| Setting | What changes | Default when never saved | Advisory or hard |
|---|---|---|---|
ASSET_REGISTER_DETAILS_TAB_ORDER | The order of the tabs on the Edit Asset screen, for everyone in the tenant. The screen reads the saved list, drops entries that no longer name a tab, and appends any tab added since at the end — so an upgrade that adds a tab puts it last rather than losing it | The declared order: Details, Transactions, Depreciation, Attachment, Related Doc, Other Journal | Cosmetic; changes no data and no validation |
On the screen and doing nothing
- Field Settings (Settings → System Configuration → Field Settings) renders eight toggles — Unit Discount, SST/VAT/GST, WHT, Blanket Order, Segment, G/L Dimension, Profit Center, Project — and a SAVE button. Nothing on that screen is saved or used, and SAVE does nothing; the same eight-toggle placeholder appears in several other master-data applets. Four of the eight — Unit Discount, SST/VAT/GST, WHT and Blanket Order — name concepts the fixed-asset form does not have at all.
- Default Branch and Default Location. Both are rendered as drop-downs on Default Selection and saved, and choosing a branch also fills Default Location with that branch’s main location. The screen also tries to record the branch’s company, but there is no field for it on the form, so no default company is ever saved. Neither saved value does anything in this applet: creating an asset still starts with Branch, Location and Company empty. (They are live settings in other applets, which is why they look as though they should work.)
- Every other setting of the document applets — the
INCLUDE_*andENABLE_*families,PRINTABLE, and fifty custom-status settings — is not shown, not saved and not used here. There is no custom-status feature on the fixed-asset screens.
Personalization
The Personalization menu lists Field Settings and Default Selection. Two problems, both in the applet’s own code:
personalizationItemspoints its first entry atfield-settings, but the personalization route has no such child (its children arepersonal-default-selectionandsidebar), so the link falls through to the applet’s404page.- The Personal Default Selection screen never assigns
appletContainer— the subscription that would populate it is commented out — so its branch and location value-change handlers dereferenceundefinedthe moment you touch either drop-down, and its SAVE emitsundefined. No personal default is ever stored.
The sidebar route is wired but is not listed in the Personalization menu.
The settings menu is partly unroutable
The settings menu in the build you are served (016ca9d0) has three groups. Three of its links lead
nowhere, and two working screens have no link at all:
| Group | Item | Where it goes |
|---|---|---|
| System Configuration | Field Settings | The eight-toggle stub described above |
| System Configuration | Default Selection | The default branch, location and tab order |
| Server Side Permissions | Permission Wizard | The applet’s 404 page — this applet declares no route for it |
| Server Side Permissions | Permission Set, User Permission, Role Permission | The shared permission listings |
| Developer Tools | Release Notes | The applet’s 404 page |
| Developer Tools | Audit Trail | The applet’s 404 page (it links to the applet-log route, which this applet does not declare) |
Opening Settings lands on the Feature Visibility screen (“Teams — Manage Team Access”), which no menu
item points to; its SAVE button has no action, so nothing on it is stored. Team Permission and the
Triggers (webhook) screen are still declared in the applet but have no menu entry — they open only
by adding team-permission-listing or webhook to the settings address.
Settings in other applets that control this applet
| Setting | Where it is set | Effect here |
|---|---|---|
Company default GL link FIXED_ASSET_REGISTER | Organization → Company | The asset GL code the purchase-invoice conversion would use. If it is absent the conversion first reuses any GL code in the tenant named exactly “Fixed Asset”, and only otherwise creates one — see below |
Item property_json.type and property_json.category_guid | Inventory Item Maintenance | Copied onto assets created by the purchase-invoice conversion. The category is only applied if the GUID resolves to an existing, readable category |
| The follow-on jobs of a purchase invoice’s finalise | BigLedger’s product configuration, not a tenant setting | Whether finalising a Purchase Invoice (Internal) creates asset records. Today the conversion is not linked to any finalise, so finalising a purchase invoice never creates an asset, on any tenant |
Who can change what
No client-side permission definitions are seeded for this applet, and the applet contains no
SHOW_*/HIDE_* permission constants. All access control is server-side, through the permission
families below. Each endpoint accepts the OWNER and ADMIN variants in addition to the one named.
| Family | Gates |
|---|---|
API_TNT_DM_FA_HEADER_* | The asset register header |
API_TNT_DM_FA_REGISTER_* | The asset container endpoints, the by-depreciation-schedule query and the report |
API_TNT_DM_FA_CATEGORY_* | Asset categories |
API_TNT_DM_FA_CONFIG_* | Per-asset depreciation configuration |
API_TNT_DM_FA_SCHEDULE_* | Depreciation schedule rows |
API_TNT_DM_FA_ATTACHMENT_* | Asset attachments |
API_TNT_DM_FA_DEPRECIATION_RUN_HDR_* | Depreciation run headers |
API_TNT_DM_FA_DEPRECIATION_RUN_LINE_* | Depreciation run lines. The RUN button needs the CREATE variant, not UPDATE |
API_TNT_DM_FA_CATEGORY_DEPRECIATION_CONFIG_* | Category-level depreciation configuration (no screen in this applet) |
API_TNT_DM_ERP_FIXED_ASSET_IMPORT_FILE_HDR_READ | The file-import listing |
Fields
Details tab (create)
The create form takes the identification you would expect — Asset Status, Asset Code, Asset Name,
Type (PROPERTY_PLANT_EQUIPMENT, LONG_TERM_INVESTMENT or INTANGIBLE_ASSET), Category, Company,
Branch, Location, Employee (person in charge), Currency, GL Code, the four analysis dimensions
(Segment, Dimension, Project, Profit Center), Serial Number, Warranty Expiry and Description. Name,
Type, Category, Company, Branch, Location and Currency carry Validators.required; nothing else
does. Five of them behave in ways the screen does not show:
| Field | What the screen does not tell you |
|---|---|
| Asset Status | Fixed to DRAFT and disabled. On the edit screen it becomes a drop-down offering Draft and Registered only. The column is free text: the shared constants name four values (ACTIVE, INACTIVE, DRAFT, REGISTERED), the depreciation processor writes a fifth (DEPRECIATED) that is in none of them. No screen writes DEPRECIATED, and the edit drop-down does not list it, so a depreciated asset opens with the box blank; picking Draft or Registered and saving replaces it. See Asset statuses |
| Asset Code | Leave it blank and the applet generates a random string of letters and digits — not a numbering series, so the codes are not sortable and carry no meaning. Uniqueness is the screen’s job: both a code you type and a generated one are compared with the codes already fetched into the browser. A typed duplicate shows “Asset Code already exists!” and disables Save; a generated duplicate shows “Auto-generated Asset Code already exists! Click save again!”. The server itself has no uniqueness rule and no unique index on the column, so a code written through the API or the CSV import is not checked |
| Employee | Selecting one stores both the entity GUID and a copy of the name, in pic_name. The copy is taken at the moment you select and is never refreshed, so renaming the employee later leaves the old name on the asset |
| GL Code | The drop-down is labelled GL Code* on create but the control carries no Validators.required, so an asset can be created without one. You find out on the Transactions tab, where every entry is refused with “Asset GL Code does not exist” until the asset has one |
| Description | Has no input control on either form. The template renders an empty <div formControlName="descr">, so a description can never be typed in. The value is still copied into the request, always empty — and the CSV import does not fill the gap either (see below) |
Purchase Date and Purchase Price are not on the create form, and they are readonly on the edit
form. The applet sends purchase_date = today and purchase_price = 0 — together with
depr_method = "DRAFT", depr_ave_method = "DRAFT", depr_start = now, depr_rate = 0 and
useful_life = 0 — because the backend rejects an empty value in every one of them — the purchase date, the
depreciation method and so on, all seven. "DRAFT" is not a
valid depreciation method; it is a placeholder that keeps the create call from failing, and it is
what a brand-new asset carries until somebody completes the Configuration sub-tab. A real purchase
price arrives by one of three routes only — an Acquisition transaction followed by Save, the CSV
import, or the purchase-invoice conversion.
Depreciation → Configuration
The sub-tab takes a depreciation start date, a method, an averaging method, a residual value, a rate, a useful life and the two depreciation GL codes. Start date, method, averaging method and both GL codes are required; residual value, rate and useful life are not. What the screen cannot show you is which of them the processor will actually look at, and in what units:
| Field | What the screen does not tell you |
|---|---|
| Depreciation Method | Four choices — NO_DEPRECIATION, STRAIGHT_LINE, DECLINING_BALANCE, DOUBLE_DECLINING_BALANCE — but the method and the averaging method are not independent. Of the eight pairings, four produce a number, two are NO_DEPRECIATION and are meant to, and two return zero with no message: declining balance and double declining balance both compute nothing under ACTUAL_DAY. See What the depreciation run computes before choosing |
| Depreciation Rate (%) | Labelled as a percentage, applied as a plain multiplier against book value once per month: bookValue.multiply(depr_rate). It is divided neither by 12 nor by 100. A rate captured the way the label reads — 20 for 20% a year — writes off twenty times the asset’s value in the first month. Used only by the two declining-balance methods |
| Useful Life (Years) | Optional on the form, and used only by straight line, as (purchase price − residual value) ÷ (useful life × 12). Every asset starts life with a useful life of zero, and a division by zero comes out as zero, so a straight-line asset whose useful life was never filled in here depreciates by nothing and reports no error |
| Residual Value | Does two jobs: it is deducted from the depreciable base and it is the run’s stop condition. At its default of zero the stop condition fires on the first run — see The stop condition |
| The two GL codes | Chosen here, but the depreciation journal reads them from the asset header, not from this row. Saving writes both copies (below); anything that writes one without the other — an API caller, or a failed second request — leaves the maths and the posting disagreeing |
Saving the edit screen writes these values to both the asset and its depreciation configuration, as two independent saves with no error handling — if the configuration save fails the asset change is still saved. The run then reads the rate and the residual value from the configuration and the GL codes from the asset, so the two copies are not interchangeable.
Transactions tab
Every entry asks for a transaction type, a date, a GL code and a description, plus the amounts that
type needs: Purchase Price for an Acquisition, Recoverable Amount and a computed Adjusted Amount for
an Adjustment, Asset Value for Asset Held for Sale, Disposal Price for a Disposal. Gain/Loss is
read-only on the last two. Only Type and Date carry Validators.required — the GL code does not, and
a journal line without one is rejected by the backend rather than by the form.
| Field | What the screen does not tell you |
|---|---|
| Transactions Type | The list you are offered depends on whether the asset already has an acquisition journal. With none, the only choice is Acquisition; with one, the other three replace it and Acquisition disappears. An asset created by the CSV import or by the purchase-invoice conversion has a purchase price but no acquisition journal, so its only offered transaction is a second acquisition, and Adjustment, Disposal and Asset Held for Sale cannot be reached from this screen at all |
| Purchase Price (Acquisition) | Posts the journal, and writes the date and price onto the asset in the browser only — the panel has no code that sends the asset. The values reach the database only if you then press Save on the asset itself. Leave the screen instead and the journal exists, the register still says purchase_price = 0, and every depreciation computed from it is zero |
| Gain/Loss | Not book value. It is your price minus the debit total of the first acquisition journal found on this asset — accumulated depreciation and every Adjustment since are ignored. “First” is not “earliest”: the query carries no sort of its own and the backend’s default is the journal’s own GUID, a random UUID, so an asset with two acquisition journals takes an arbitrary one |
| Adjusted Amount | Same base: recoverable amount minus that acquisition total. It is computed when you press the calculate control, not as you type |
Import Fixed Asset (CSV columns)
code, name, type, category_code, company_code, branch_code, location_code, currency,
gl_code, purchase_date, purchase_price, serial_number, warranty_expiry, employee_name,
description.
Only code and name are checked for emptiness up front. Every code column is resolved by lookup
and throws a specific message on failure — <INVALID CATEGORY CODE>, <INVALID COMPANY CODE>,
<INVALID HDR BRANCH CODE>, <INVALID LOCATION CODE>, <INVALID GL CODE>, <INVALID EMPLOYEE NAME>, <INVALID LEDGER CODE>. The employee is matched on name, not code. The GL code is
matched on gl_code_1. If no subledger exists for the resolved GL code and company, the import
creates one.
There are no depreciation columns in the import. Imported assets carry the same "DRAFT" and zero
placeholders a hand-created asset gets, have no depreciation configuration row and no schedule, and
so will not be picked up by a depreciation run or appear in the report until both are added by hand —
one asset at a time, one schedule month at a time.
Two more things the template does not say. The description column is parsed and thrown away:
the column is declared on the staging row and the row builder never calls setDescr on the asset, so
the import is not a way round the Description field having no input control. And an imported asset gets an
employee_guid but no pic_name, where an asset created on screen gets both — so the person-in-charge
name is blank on imported rows even when the employee resolved.
Lifecycle and effects
Asset statuses
DRAFT → REGISTERED → (DEPRECIATED, set by a depreciation run). An asset’s status can also be
ACTIVE or INACTIVE through the API. The screen offers Draft and Registered, and shows Disposed
once a disposal has been posted — after which the status drop-down offers Disposed alone. A
depreciation run does not respect it: the run selects by schedule month, not by status, and marks every
asset it processes DEPRECIATED, so a month scheduled after the disposal is still depreciated and the
asset stops showing as Disposed. Add schedule months no further ahead than you need, and check a disposed
asset’s status after each run.
The Save rule is the one in the callout under Depreciation → Configuration: a valid Details form for a Draft asset, valid Details and Configuration forms for a Registered one, and an acquisition transaction before a Registered asset saves.
Posting a disposal marks the asset Disposed. When a Disposal transaction is posted on the
Transactions tab, the open asset’s status becomes DISPOSED with the transaction’s date as its
disposal date, and the screen says Asset marked as Disposed. Press Save to keep the change. The
status is stored only when you then press Save; leave without saving and the asset keeps its
old status while the disposal journal stands.
What creates a journal
Nothing here goes through the ordinary document posting. Every journal is assembled and sent by the applet or by the depreciation run.
Transactions tab — the browser builds the journal lines, sums them, refuses to send if debits do not equal credits (a toast in the browser, “Journal Transaction is not balanced” — the balance check is the screen’s job; the journal endpoint does not repeat it), and then posts the journal. Every journal this applet writes is posted the moment it is written, on the company’s primary ledger — there is no draft to review. None of them reads a company default GL link: each one posts to the GL codes on the asset and the GL codes you pick on the form:
| Type | Debit | Credit | Amount |
|---|---|---|---|
| Acquisition | asset GL code | the GL code you pick | Purchase Price. The date and price are also written onto the asset in the browser only — see the Transactions tab above; they are persisted by the asset’s own Save, not by this panel |
| Adjustment (amount ≥ 0) | the GL code you pick | asset GL code | Adjusted Amount |
| Adjustment (amount < 0) | asset GL code | (undefined) | Absolute Adjusted Amount. The credit line goes out with no GL code, so the journal is rejected |
| Disposal | asset GL code, at the acquisition amount; a gain on the gain/loss GL code | the GL code you pick, at the Disposal Price; a loss on the gain/loss GL code | The mirror image of a conventional disposal — see the callout above |
| Asset Held for Sale | the same as Disposal | the same as Disposal, at the Asset Value | The same mirror image |
Disposal does not reverse accumulated depreciation; the entry is written against the acquisition amount, not the net book value.
Other Journal tab — a free-form journal of transaction type TXN: one “main” line plus any number
of Payment Breakdown rows, each line debited if its amount is positive and credited if negative, with
the same client-side balance check.
None of these lines names a subledger. That is fine: the journal finds the subledger from the line’s GL code and company, and creates one if none exists.
Depreciation run — see below.
The depreciation run, step by step
- You create a run header: company (required), branch (optional), month and year.
- You open the run, go to the Lines tab, press
+, and press RUN on the Registered Assets screen. That needsAPI_TNT_DM_FA_DEPRECIATION_RUN_LINE_CREATE. - The backend permanently deletes every existing line on that run, and the journals of those lines
that it can find, then rebuilds. It can only find a journal that has at least one line for the
asset — and the depreciation journal usually has none (see
The depreciation journal), so a re-run normally leaves the earlier
empty journal in place and adds another one. Count the
DEPRECIATIONjournals for the month in Ledger and Journal after a re-run. - It selects the assets that have both a depreciation configuration and a schedule row for
that month and year. An asset with no configuration, or no
schedule row for the month, is silently skipped. The asset’s own status is not a condition: a
DRAFTasset with a configuration and a schedule row is depreciated exactly like aREGISTEREDone, even though the screen that lists them is called Registered Assets. - One run line is created per selected asset, copying the method, averaging method, rate, useful life, residual value, purchase price, purchase date and disposal date onto the line, and each line is depreciated at once, inside the same request, rather than left for a background worker.
Nothing runs depreciation on a timetable. Pressing RUN is the only thing that creates a line, and depreciation only ever acts on a line that already exists. There is nothing for a schedule to trigger. A month in which nobody opens a run and presses RUN is simply not depreciated, and nothing reports its absence.
The selection ignores the run’s company and branch, and is capped at 100 assets. It filters on the month and year only. A run therefore processes at most 100 assets — from every company in the tenant, ordered by asset GUID — while stamping the run header’s company and branch onto every journal it writes.
The list you look at before pressing RUN is not the list the run processes. The Registered Assets grid shows the same selection limited to the run’s company (not its branch), so the preview is scoped to the run’s company and the run is not. Nothing on the screen says so.
Two more things about the selection that the screen cannot show:
- The Advanced Search panel on Registered Assets changes nothing. It sends company, branch, location, a purchase-date range and an asset-code range, and the screen’s query uses only the company, branch, location and the schedule month and year. The rest are accepted and dropped. The same filters do work on the Asset Register listing.
- A month added twice is depreciated twice. The Add Depreciation panel has no duplicate check, and the selection takes every schedule row, so two schedule rows for the same month yield two run lines for that asset in that month. Each one sums only the lines dated strictly before the month it is processing, so neither sees the other: both compute the same amount, both write the same accumulated depreciation onto the asset, and both post a journal. The ledger moves twice; the asset’s accumulated depreciation moves once.
What the depreciation run computes
| Averaging method | Straight Line | Declining Balance | Double Declining Balance |
|---|---|---|---|
FULL_MONTH | (purchase price − residual value) ÷ (useful life × 12) | (purchase price − accumulated depreciation) × rate | (purchase price − accumulated depreciation) × rate × 2 |
ACTUAL_DAY | (purchase price − residual value) ÷ days in the purchase month × days counted — see below | returns zero | returns zero |
ACTUAL_DAY is only worked out for straight line; for any other method it gives zero.
NO_DEPRECIATION gives zero under both averaging methods, as intended.
ACTUAL_DAY does not prorate the month being depreciated, and it never divides by the useful life.
Both the divisor and the multiplier are taken from the purchase date’s month. They are set to the
same number and only differ when the month being run is the purchase month, in which case the
multiplier becomes the days from the purchase date to the end of that month. In every other month the
two cancel and the result is the whole of purchase price − residual value — the entire depreciable
value, in one month. Choose FULL_MONTH unless you have confirmed otherwise on your own tenant.The rate is applied as written: book value × rate, once per month, with no division by 12 and no division by 100. A rate captured as an annual percentage will depreciate far too fast.
Several of the inputs are not read from the database at the moment of calculation. The whole asset — its purchase price, its accumulated depreciation and its depreciation configuration — is copied when the run line is created and read back from that copy. The purchase price and accumulated depreciation the declining-balance formulas divide by are therefore the values as they stood when RUN was pressed, not as they stand when the line runs. That is why two lines for the same asset and month (above) produce the same number rather than a diminishing one.
The stop condition, and the status flip
After computing the month’s amount the run sums the earlier run lines, adds the new amount, and then branches on
new accumulated depreciation ≤ residual value- True — it saves the amount, the new accumulated depreciation and the net book value
(
purchase price − accumulated depreciation) on the run line, writes the accumulated depreciation back onto the asset header, sets the asset’s status toDEPRECIATED, and creates the journal. - False — it sets the asset’s status to
DEPRECIATEDand then permanently deletes this asset’s run lines from this month to the end of this year, together with the journals it can find for them — and every later year’s lines, as the callout below explains. No journal is created for this month.
“Earlier lines” and “later lines” are not limited to this asset once a year boundary is crossed. The query behind both steps asks for lines of an earlier year, or lines of this asset earlier in this year — the asset condition binds only to the same-year half. So:
- From the second year on, the sum includes every asset’s run lines from every earlier year. One asset’s accumulated depreciation picks up the whole tenant’s prior-year depreciation, which makes the stop condition false almost at once.
- Running a month while a later year already has run lines deletes every asset’s run lines in that later year, with whatever journals the delete can find (on the false branch, which is the usual one). Lines of a deleted run still count, in both directions.
Before you run a month in a second year, or re-run a month after a later year has been run, export the
run lines and the DEPRECIATION journals of the later months, run it, and compare.
With the usual residual value of zero, any positive depreciation amount makes the comparison false on
the very first run. The asset is marked DEPRECIATED and no depreciation journal is written.
The order of the writes matters if the journal fails. On the true branch the run updates the run
line, then writes the accumulated depreciation and the DEPRECIATED status onto the asset, and only
then builds and posts the journal, separately. If the journal fails, the run line and the asset keep
the values already written. The visible result is an asset whose accumulated depreciation has moved
with no journal behind it. Re-running the month is the recovery — it deletes the line and rebuilds —
but nothing on any screen tells you the month needs re-running: the failure is recorded in a job error
log that no applet shows.
The depreciation journal
The journal is written directly by the run, not through the ordinary document posting. It carries
transaction type DEPRECIATION, is marked automatic and is posted from the moment it is created —
there is no draft to review — and both the header and the two lines are described as
AUTO CREATED FROM FIXED ASSET DEPRECIATION PROCESSOR. To find these in
Ledger and Journal, filter on that transaction type;
each one also records the asset and the run line that produced it.
Four of its properties are worth knowing because they come from somewhere other than where you would look:
| Property | Where it comes from, and why that matters |
|---|---|
| Company and branch | From the run header, not from the asset. Because the run’s asset selection ignores company entirely (above), a journal can be stamped with one company while depreciating an asset that belongs to another |
| Currency | From the asset’s currency, while the ledger is the run company’s primary ledger. A foreign-currency asset writes a foreign-currency journal into that ledger |
| The two GL codes | The two depreciation GL codes on the asset — not the depreciation configuration you filled in, which holds its own copy of both. Saving the edit screen writes both copies; anything that writes only one leaves them disagreeing |
| Dates | The transaction and document dates are the first of the depreciated month, while the posting date is the moment RUN was pressed. Re-running an old month therefore back-dates the entry and stamps today’s posting date |
Each depreciation line is added to the journal only if the asset carries a subledger for it — one for depreciation expense and one for accumulated depreciation — and nothing sets either: no screen has a field for them, and the Configuration sub-tab writes the two GL codes and stops. The asset’s own subledger, which the CSV import and the purchase-invoice conversion do fill in, is a different one, and the depreciation journal does not use it.
Unless the two subledgers are set on the asset through the API, both lines are dropped and the run creates a journal header with no lines and zero debits and credits. The journal validator does not reject an empty or unbalanced journal, so nothing surfaces an error, and the run still reports success.
The two lines are also merged when they share a subledger: debits and credits are summed into the first line, keeping that line’s GL code. Point both configuration GL codes at the same subledger and the expense and the accumulation become a single line whose debit and credit cancel.
Asset creation from a purchase invoice
Nothing starts this conversion today. It is written as a follow-on job of finalising a purchase invoice, but in BigLedger’s product configuration it is linked to no finalise, so finalising a Purchase Invoice (Internal) creates no asset on any tenant, and no screen in this applet or the purchase invoice offers to run it. If you buy fixed assets on a purchase invoice, create each asset by hand (or by CSV import) and record its acquisition on the Transactions tab. What follows is what the conversion does when it runs, so you can recognise its records if it is switched on.
It reads a purchase invoice and picks the lines whose item is a fixed-asset item (item type
FIXED_ASSET_REGISTER) — on an INTERNAL_PURCHASE_INVOICE only.
For each such line it creates one asset (not one per unit) with:
- the code from a running number (not the item code), and the name from the line’s item name; quantity = the line’s base quantity
- purchase price = line amount ÷ base quantity — the unit price
- company, branch, location and transaction date from the document header — only those: segment, dimension, project and profit centre are not copied
- serial numbers from the line, joined into one comma-separated string
- asset type and category from the item’s fixed-asset settings
- GL code from the company’s
FIXED_ASSET_REGISTERdefault GL link. If the company has none, it first reuses any GL code in the tenant named exactly “Fixed Asset” — whichever company’s chart it belongs to — and only if there is none creates a GL code named “Fixed Asset Register” (under the GL categoryinventory); either way it then writes the company’s default link - the asset’s subledger found (or created) for that GL code and company
- asset status
DRAFT, and the same"DRAFT"/ zero placeholders for the depreciation fields
It posts no journal. On success it marks the invoice’s fixed-asset posting flag as POSTED — a flag of
its own, separate from the invoice’s record status and from its posting status (Draft / Final / Void) — which is also what stops the
conversion running twice (POSTED or VOID are both skipped). A line that fails is only logged.
Related applets
- Purchase Invoice (Internal) — the document whose fixed-asset lines can become asset records.
- Inventory Item Maintenance — where an item is marked as a fixed-asset item and given its default asset type and category.
- Chart of Account — supplies all three GL codes and the primary ledger the journals are stamped with.
- Ledger and Journal — where every journal this applet
writes can be found; filter on transaction type
DEPRECIATIONorTXN, or on the acquisition, adjustment and disposal types. - Organization — company, branch, location and the company default GL link used by the purchase conversion.
- Employee — the person-in-charge drop-down.
- Financial Report — where depreciation reaches the statements.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| RUN says “Successfully run the depreciation” and the Lines tab is empty | The toast fires on any response, and the grid is not refreshed. The commonest real cause is that no asset matched: the selection needs a depreciation configuration and a schedule row for that exact month | Reopen the run’s Lines tab. If it is still empty, open an asset and check Depreciation → Configuration and Depreciation → Schedule |
| Run lines exist but the journals have no lines | A journal line is added only when the asset carries a depreciation subledger, and nothing sets one | BigLedger is tracking this. Until it is fixed, treat the depreciation journal as not produced and post depreciation from Ledger and Journal |
An asset is marked DEPRECIATED after one run and never depreciates again | The stop condition compares accumulated depreciation against the residual value; with a residual value of zero it is false on the first run | Understand the flag as “the run has touched this asset”, not “fully depreciated”. Re-running the month deletes and recreates the lines |
| A run picks up assets from another company | The run’s selection filters only on month and year, not on company, branch or location | Check the run’s lines before relying on them, and reconcile the journals by the run header’s company |
| A run only ever produces about 100 lines | The run’s selection stops at 100 assets | Splitting the month across several runs does not help — the selection is identical each time, so there is no configuration that works around it. Depreciate the remaining assets through a manual journal for now, and report it as a product defect: send the run’s company, the month, the number of assets you expected and the number of lines you got (what to send) |
| An acquisition was entered but the asset still shows Purchase Price 0 | The Add Transaction panel posts the journal and writes the price onto the asset in the browser only; nothing sends the asset | After adding an Acquisition, press Save on the asset before leaving the screen. If you have already left, reopen the asset, re-enter the price path, or correct it through the API |
| Adjustment, Disposal and Asset Held for Sale are missing from the transaction type list | The list depends on whether the asset has an acquisition journal. Assets created by the CSV import or the purchase-invoice conversion have a purchase price but no acquisition journal | Add an Acquisition transaction first, or post the disposal directly in Ledger and Journal |
| The Advanced Search on the Registered Assets screen changes nothing | That screen uses only company, branch, location and the schedule month and year; the code and date criteria are dropped | Use the Asset Register listing for those filters |
| An asset never appears on a run | The selection needs a depreciation configuration and a schedule row for that exact month and year | Open the asset → Depreciation → Configuration and complete it, then Depreciation → Schedule → + and add the month |
| An asset never appears on the report | The report needs a depreciation configuration, a schedule row and a completed depreciation run inside the month range — assets that have never been run are left out | Complete the configuration and the schedule, then run the month. The report shows depreciation that happened, not assets that exist |
| A negative Adjustment transaction is rejected | The credit line of a negative adjustment is sent with no GL code, so the journal is rejected (..._JOURNAL_LINE_OBJECT_GLCODE_GUID_IS_NULL) | Record the reversal as a positive adjustment in the opposite direction, or use the Other Journal tab |
| “Journal Transaction is not balanced” on the Transactions or Other Journal tab | A client-side check in the browser, before anything is sent | Correct the amounts. This is not a backend rejection |
| “Asset GL Code does not exist” when adding a transaction | The asset has no GL code. Possible because GL Code is not required on the create form | Open the asset’s Details tab and set the GL Code, then save |
| Saving the edit screen updates the asset but not its depreciation configuration | Save makes two independent saves with no error handling | Reopen the asset and check the Configuration tab; re-save if the values did not stick |
| The Description field cannot be filled in | Neither form has an input for it, and the CSV import reads its description column without storing it | Use the Attachment tab’s Details field, or set the description through the API |
| Permission Wizard, Release Notes or Audit Trail opens a 404 | The shared settings menu in the build you are served renders those links but this applet declares no route for them | Use the Permission Set, User Permission and Role Permission listings here, or another applet for the wizard |
| Personalization → Field Settings opens a 404, and Personal Default Selection saves nothing | The personalization menu points at a route that does not exist, and the personal settings component never populates its container | Use Settings → Default Selection instead |
An imported row fails with <INVALID EMPLOYEE NAME> | The import matches employees by entity name, exactly | Correct the name in the CSV, or clear the column |
An imported row fails with <INVALID LEDGER CODE> | The import looks for the ledger whose code is PRIMARY — not scoped to the row’s company. It takes the first match in the tenant | The tenant needs a ledger whose code is literally PRIMARY. In a multi-company tenant, check which one the subledgers it creates were attached to |
| Two assets have the same Asset Code | The duplicate check is the create screen’s: it compares the code — typed or generated — with the codes already fetched into the browser. The server has no uniqueness rule and no unique index, so codes from the CSV import or the API are not checked | Check the listing after an import, and fix duplicates on the Edit screen |
Related documentation
- Financial Accounting module
- Clone, correct or remove a manual journal › Step 6 — the guide for posting each month’s depreciation as a journal, from the asset’s Depreciation Schedule.
- Ledger and Journal
- Chart of Account
- Financial Report