Skip to content

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 jobScreen or tabRead
Register an assetAsset 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 assetAsset Register, then the asset’s Transactions tabAsset 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 firstEdit asset, Transactions tabTransactions tab; What creates a journal
Set how it depreciates — a month with no schedule row is skippedEdit asset, Depreciation › Configuration and ScheduleDepreciation → 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 JournalDepreciation Run › the run › Lines › + › RUNThe depreciation run, step by step; The depreciation journal
Load assets from a fileImport Fixed AssetImport 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.

Post depreciation as a journal until the run is fixed, and try the run on a copy first. RUN starts the depreciation run on the server, but the journal it writes has no lines unless two depreciation subledgers are set on the asset through the API, and with a residual value of zero the first run marks the asset 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

DirectionWhatWhy
UpstreamPurchase 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)
UpstreamInventory Item MaintenanceThe item’s property_json carries the type and category_guid copied onto the converted asset
UpstreamChart of AccountSupplies the asset GL code, the depreciation-expense GL code and the accumulated-depreciation GL code
UpstreamOrganizationCompany, branch and location; the company’s FIXED_ASSET_REGISTER default GL link used by the purchase conversion
UpstreamEmployeeThe person-in-charge drop-down reads entity headers
DownstreamLedger and JournalEvery acquisition, adjustment, disposal, other journal and depreciation line lands here as a journal
DownstreamFinancial ReportDepreciation 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.

MenuRouteWhat it shows
Asset Registerasset-registerThe asset listing, plus create and edit
Asset Categoryasset-categoryThe category master
Depreciation Rundepreciation-runMonthly run headers and their result lines
ReportsreportsThe fixed-asset report with PDF and XLS export
Import Fixed Assetfile-importCSV 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 New Asset form beside the asset register listing, showing Asset Status fixed to DRAFT and the required Asset Name, Type, Category, Company, Branch, Location and Currency controls

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 Asset Register form showing Asset Status, Asset Code, Asset Name, Type, Category, Company, Branch, Location, Purchase Date and Purchase Price

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 Transaction panel with Transactions Type set to Acquisition and Purchase Date, Purchase Price, GL Code and Description fields
The Depreciation Schedule grid beside the Add Depreciation panel with From and To month pickers

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.

The Attachment grid beside the Add Attachment panel with an Attachment Name field, a Details field and a drag-and-drop upload area
The Other Journal grid beside the Add Other Journal panel with Date, Description, Amount Paid, GL Code and a Payment Breakdown section

Asset Category

Asset Register Category Listing with Category Code, Category Name, Creation Date, Modified Date and Status columns

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

Depreciation Run Listing with Company, Branch, Month and Year columns

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

Fixed Asset Register File Import Listing with File Name, File Size, Format, Status and Process Status columns

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 fixed-asset report grid grouped by Company and Category Code, with Export PDF and Export XLS buttons

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_method and averaging_method, where the columns are depr_method and depr_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

PrerequisiteWhere it is setWhy it matters here
A chart of accounts with an asset GL code, a depreciation-expense GL code and an accumulated-depreciation GL codeChart of AccountAll 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 locationOrganizationCompany, Branch and Location are required on the asset form
A company FIXED_ASSET_REGISTER default GL linkOrganization → CompanyThe 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 AccountEvery 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 categoryThis applet → Asset CategoryCategory is required on the asset form
Employee entitiesEmployeeOnly 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.

SettingWhat changesDefault when never savedAdvisory or hard
ASSET_REGISTER_DETAILS_TAB_ORDERThe 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 itThe declared order: Details, Transactions, Depreciation, Attachment, Related Doc, Other JournalCosmetic; 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_* and ENABLE_* 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:

  • personalizationItems points its first entry at field-settings, but the personalization route has no such child (its children are personal-default-selection and sidebar), so the link falls through to the applet’s 404 page.
  • 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 dereference undefined the moment you touch either drop-down, and its SAVE emits undefined. 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:

GroupItemWhere it goes
System ConfigurationField SettingsThe eight-toggle stub described above
System ConfigurationDefault SelectionThe default branch, location and tab order
Server Side PermissionsPermission WizardThe applet’s 404 page — this applet declares no route for it
Server Side PermissionsPermission Set, User Permission, Role PermissionThe shared permission listings
Developer ToolsRelease NotesThe applet’s 404 page
Developer ToolsAudit TrailThe 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

SettingWhere it is setEffect here
Company default GL link FIXED_ASSET_REGISTEROrganization → CompanyThe 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_guidInventory Item MaintenanceCopied 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 finaliseBigLedger’s product configuration, not a tenant settingWhether 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.

FamilyGates
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_READThe 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:

FieldWhat the screen does not tell you
Asset StatusFixed 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 CodeLeave 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
EmployeeSelecting 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 CodeThe 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
DescriptionHas 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:

FieldWhat the screen does not tell you
Depreciation MethodFour 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 ValueDoes 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 codesChosen 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.

Save needs a valid configuration; a registered asset also needs an acquisition. Save is enabled for a Draft (or Disposed) asset whose Details form is valid, and for a Registered asset whose Details and Configuration forms are both valid, whichever form you edited last. Pressing Save on a Registered asset with no acquisition transaction shows A registered asset needs an acquisition transaction and saves nothing.

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.

FieldWhat the screen does not tell you
Transactions TypeThe 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/LossNot 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 AmountSame base: recoverable amount minus that acquisition total. It is computed when you press the calculate control, not as you type
The disposal entry is the mirror image of the conventional one. Disposal and Asset Held for Sale both debit the asset GL code by the acquisition amount and credit the GL code you pick by the disposal price or asset value. The gain or loss line is flipped too: a gain is debited and a loss is credited to the gain/loss GL code. Sell an asset that cost RM 5,000 for RM 6,000 and you get Dr asset 5,000, Dr gain 1,000, Cr the account you picked 6,000 — the entry balances, so nothing refuses it, but every line is on the wrong side. A conventional disposal credits the asset out of the balance sheet; this one adds to it. Nothing reverses accumulated depreciation either. Before you rely on the balance sheet, open the journal in Ledger and Journal (filter on the asset, transaction type Disposal or Asset Held for Sale) and post the conventional entry yourself — Cr asset at cost, Dr the proceeds account, gain credited or loss debited — with a reversal of this one.

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:

TypeDebitCreditAmount
Acquisitionasset GL codethe GL code you pickPurchase 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 pickasset GL codeAdjusted 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
Disposalasset GL code, at the acquisition amount; a gain on the gain/loss GL codethe GL code you pick, at the Disposal Price; a loss on the gain/loss GL codeThe mirror image of a conventional disposal — see the callout above
Asset Held for Salethe same as Disposalthe same as Disposal, at the Asset ValueThe 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

  1. You create a run header: company (required), branch (optional), month and year.
  2. You open the run, go to the Lines tab, press +, and press RUN on the Registered Assets screen. That needs API_TNT_DM_FA_DEPRECIATION_RUN_LINE_CREATE.
  3. 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 DEPRECIATION journals for the month in Ledger and Journal after a re-run.
  4. 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 DRAFT asset with a configuration and a schedule row is depreciated exactly like a REGISTERED one, even though the screen that lists them is called Registered Assets.
  5. 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.

RUN says “Successfully run the depreciation” whatever happened. The toast is fired from the success callback of the HTTP request, with nothing read out of the response. A run that matched no asset at all — the normal outcome when the assets have no depreciation configuration or no schedule row for that month — shows the same message. The Lines grid is not refreshed either, so it keeps showing whatever it showed before. Open the Lines tab and count the rows; that is the only confirmation the screen offers.

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 methodStraight LineDeclining BalanceDouble 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 belowreturns zeroreturns 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 to DEPRECIATED, and creates the journal.
  • False — it sets the asset’s status to DEPRECIATED and 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:

PropertyWhere it comes from, and why that matters
Company and branchFrom 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
CurrencyFrom 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 codesThe 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
DatesThe 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_REGISTER default 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 category inventory); 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 DEPRECIATION or TXN, 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

SymptomCauseFix
RUN says “Successfully run the depreciation” and the Lines tab is emptyThe 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 monthReopen 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 linesA journal line is added only when the asset carries a depreciation subledger, and nothing sets oneBigLedger 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 againThe stop condition compares accumulated depreciation against the residual value; with a residual value of zero it is false on the first runUnderstand 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 companyThe run’s selection filters only on month and year, not on company, branch or locationCheck 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 linesThe run’s selection stops at 100 assetsSplitting 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 0The Add Transaction panel posts the journal and writes the price onto the asset in the browser only; nothing sends the assetAfter 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 listThe 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 journalAdd an Acquisition transaction first, or post the disposal directly in Ledger and Journal
The Advanced Search on the Registered Assets screen changes nothingThat screen uses only company, branch, location and the schedule month and year; the code and date criteria are droppedUse the Asset Register listing for those filters
An asset never appears on a runThe selection needs a depreciation configuration and a schedule row for that exact month and yearOpen the asset → Depreciation → Configuration and complete it, then Depreciation → Schedule → + and add the month
An asset never appears on the reportThe 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 outComplete the configuration and the schedule, then run the month. The report shows depreciation that happened, not assets that exist
A negative Adjustment transaction is rejectedThe 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 tabA client-side check in the browser, before anything is sentCorrect the amounts. This is not a backend rejection
“Asset GL Code does not exist” when adding a transactionThe asset has no GL code. Possible because GL Code is not required on the create formOpen the asset’s Details tab and set the GL Code, then save
Saving the edit screen updates the asset but not its depreciation configurationSave makes two independent saves with no error handlingReopen the asset and check the Configuration tab; re-save if the values did not stick
The Description field cannot be filled inNeither form has an input for it, and the CSV import reads its description column without storing itUse the Attachment tab’s Details field, or set the description through the API
Permission Wizard, Release Notes or Audit Trail opens a 404The shared settings menu in the build you are served renders those links but this applet declares no route for themUse 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 nothingThe personalization menu points at a route that does not exist, and the personal settings component never populates its containerUse Settings → Default Selection instead
An imported row fails with <INVALID EMPLOYEE NAME>The import matches employees by entity name, exactlyCorrect 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 tenantThe 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 CodeThe 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 checkedCheck the listing after an import, and fix duplicates on the Edit screen

Related documentation

Last updated on