Skip to content

Item Master Extensions

You look after the item master at GadgetSphere — about 5,200 SKUs shared by three companies — and three questions keep coming back: why does a smartphone sold by the online company post to the retail company’s sales account?, where do product photos actually live?, and why did an e-Invoice go out without a classification code? All three are answered by records that hang off the item but are not the item: the extension rows, the images, the per-company GL code links and the LHDN classification. This page explains what each one is, which screen writes it and what reads it, then walks the one procedure a multi-company retailer needs — posting the same item to different accounts in different companies. Reading it takes fifteen minutes; the procedure takes about five minutes per product family.

Meet GadgetSphere

GadgetSphere Sdn Bhd (GS) sells flagship smartphones over the counter in 22 branches. GadgetSphere Online Sdn Bhd (GSO) sells the same SKUs from a web store, and GadgetSphere Distribution Sdn Bhd (GSD) sells them wholesale. One item record, SP-FLAG-256, serves all three — but GS wants its sales in SALES-SMARTPHONE-KV01-style branch accounts, GSO wants everything in SALES-ONLINE-GSO, and the group accountant wants purchases of that phone in COST-SMARTPHONE whichever company bought it. That is a per-company GL code problem, and it is the first thing this page solves.

Four things that hang off an item

An item in BigLedger is one header row (bl_fi_mst_item_hdr — code, name, type, UOM, tax, the GL code on the Main tab) plus lines for its units of measure and child items. Around that sit four families of records that the item screen writes and other parts of the system read:

What you see on the screenWhat it isWhere it is storedWho has it
Checkboxes and small fields on Create / Edit — Track inventory, Serialised, Ecom sync, Remarks, PrefixExtension rows — one row per named key, a plain key-value store on the itembl_fi_mst_item_ext79 of 90 tenants; the largest business table on the platform at ~24 M rows
Manage Media tabImages — one row per uploaded picture, pointing at a file in the platform’s file storebl_fi_mst_item_image_hdr26 of 90 tenants, ~220,000 pictures
Company Linking → GL Codes tabPer-company GL codes — up to six rows per item per company, keyed by what kind of transaction is postingbl_fi_mst_item_company_glcode_link25 of 90 tenants
E-Invoice tab → Item classificationLHDN classification — a pointer from the item to one of the 45 codes the tax authority publishesbl_fi_mst_item_classification_hdr (the list) and three columns on the item headerThe list is in every tenant; 66 tenants have classified their items

Take them in turn.

The extension rows — a key-value store on the item

Every item can carry any number of extension rows. Each row is a key (param_code, echoed in param_name), a type (param_type: STRING, NUMERIC, DATE, JSON or FILE) and a value in the matching column (value_string, value_numeric, value_datetime, value_json or value_file). The developers’ comment on the table says it plainly: “to store additional attributes for the item.” There is no registry of allowed keys — the backend checks that a row has a guid, belongs to the item, has a revision and a status, and nothing else.

In practice the 24 million rows across the platform are a small number of keys, and it helps to know which ones matter:

KeyWritten byRead byWhat it means for you
TRACKING_INVENTORY (true / false)The Create item screen, for Basic Item only, from the Track inventory checkboxThe Doc Item Maintenance applet itself, right after the first save, to decide whether to create the matching inventory item record (the physical stock record the Inventory Item Maintenance applet keeps); the item exportIf this is false, the item never gets a stock record and never moves stock. Once the inventory item exists, changing the flag does not remove it
SERIALIZEDThe Create / Edit screenCopied to the inventory item’s own extension row when the stock record is created; the item-code serviceWhether each unit carries a serial number. The stock-side copy is the one the serial-number screens consult
ECOM_SYNC_CHECKEDThe Create screen and the CSV import (Ecom sync column)The marketplace and web-store connectors, which also write it backWhether the item is offered to e-commerce listings
REMARKS, ABBREVIATION (from the Prefix field), ITEM_STATUS, OBSOLETE_DATE, GL_CODE, COUPON_VALID_PERIOD, MTO_GROUP_DISCOUNT_*The Create / Edit screen, one row each when the field is filledThe same screen, and the voucher applet for ABBREVIATIONOrdinary fields that happen to be stored as rows
ITEM_ATTACHMENT (type FILE)Uploading a file (not an image) to the itemThe screen; nothing posts or prints itAn attachment — a spec sheet, a warranty card PDF. See the next section for how it differs from an image
SETTLEMENT_TYPE, CASHBOOK_CODE, FPX_*, CHARGES_*, SURCHARGE_TO_CUSTOMER_*, PAYMENT_PROVIDER_*The PNS Settlement Method tab and the settlement-method importThe POS payment buttons and the payment-channel screensOnly on items that are payment methods, not stock. Covered on Payment aggregators and settlement methods
EMP_ITEM_* (17 keys)The migration from the legacy Wavelet EMP productNothing in the current productWhere the row count comes from: 48 tenants were migrated, and each migrated item carries 17 of these. They are inert. Do not delete them, and do not expect them on items created in BigLedger

Three facts about how the rows behave, all verified against the applet and the backend:

  • A key is one row, updated in place. The Edit screen finds the row by param_name and overwrites its value; it does not add a second row. Duplicates do exist (39 tenants hold about 6,800 duplicate item-and-key pairs, from imports and older versions), and where they do, the screen reads the first one it finds.
  • The document applets do not read these flags. Nothing in the POS or the sales and purchase document applets checks TRACKING_INVENTORY or SERIALIZED on the item. Whether a line moves stock is decided by the document type and by whether the inventory item record exists (see Costing internals). Whether a serial number is demanded is decided on the stock side. So a wrong flag shows up as a missing stock record or a missing serial prompt, never as a message naming the flag.
  • ext_code, ext_type, ext_option and the line scope are designed and unused. The comment on ext_code describes a future template link; in production the column is empty on 99.99% of rows (the only system value is SYSTEM_DEFAULT on attachments). item_line_guid — “may be empty if the extension is meant for document header only” — is set on 2% of rows, all written by marketplace connectors.

Images and attachments — two tables, one word

The Manage Media tab and the attachments control on the item look similar and go to different places:

You upload…Endpoint the screen callsRow createdType markerServed to the public?
A picture on the Manage Media tab…/financial-items/add-images/{item}bl_fi_mst_item_image_hdr, param_code ITEM_ATTACHMENT, param_type FILEimage_type = PUBLIC_READ_ONLY if you tick publicYes — …/pub/image-file/{guid} serves it without a login
A file attached to the item…/financial-items/add-files/{item}bl_fi_mst_item_ext, same ITEM_ATTACHMENT / FILE markersext_type = PUBLIC_READ_ONLY if publicNo public URL

Both point at a row in the platform’s file store (value_file is the file’s guid — the column comment says exactly that). An item can have any number of images; the backend validates the row’s guid, item and status and nothing about count or order. The seq_no column exists for ordering and is empty on 98.5% of rows in production, so if your web store shows pictures in an unexpected order, the order is whatever the connector chose, not a sequence you set here.

Deleting an image from Manage Media marks the row DELETED and then removes the file record and the stored object — the row stays (28% of image rows on the platform are deleted ones), the picture is gone. Creating an alias item copies the original’s images as new files.

Images reach the marketplaces through the marketplace-sync job, which pushes item images to listings. Pictures the connectors pull from a marketplace are recorded under the marketplace item’s own records, which may point back at an image row here but are not the same thing.

Per-company GL codes — which account a line posts to

This is the part that answers GadgetSphere’s first question, and it needs the whole rule, because the GL code link is the third of four places the posting engine looks:

  1. A GL code on the document line wins outright (the accounts clerk picked it on the invoice).
  2. Otherwise a GL code on the document header — and note this beats the item link.
  3. Otherwise the item-company link for this company and this item, filtered by the transaction code.
  4. Otherwise the company’s default GL code for the same transaction code — the “Default GL Codes” that every company must have, or FINAL fails with MISSING_DEFAULT_GL_CODE.

The transaction code is set by the document, not by you: SALES for sales-side documents, PURCHASE for purchase-side, SALES_RETURN and PURCHASE_RETURN for the return documents (sales return, purchase return, consignment return). Two more codes — SALES_DISCOUNT and PURCHASE_DISCOUNT — are offered on the screen and accepted by the backend, and the posting engine resolves a discount code but never uses it for the lookup, so a link saved under them has no effect today. Documents that post under other codes — a purchase GRN stock-in (INVENTORY_NOT_INVOICED), a stock adjustment (STOCK_ADJUSTMENT), consignment stock (CONSIGNMENT_STOCK) — cannot be given an item-level link at all, because the backend only accepts the six codes above; they always use the company default unless the line or header names a GL code.

A link row is item + company + chart of accounts + GL code + transaction code. The backend checks that each of those exists when given and that the code is one of the six; it does not check that the combination is unique, and the posting engine takes the first matching row it finds, in no defined order. Keep one row per item, company and code. Note also what the screen does on first save (below): it writes a row for every one of the six codes, including the ones you left empty, which is why 38% of link rows on the platform carry no GL code. An empty row is harmless — the engine falls through to the company default — but it is why the GET listing looks fuller than what you set.

The LHDN classification — 45 codes, one list

The Classifications menu shows the list the Malaysian tax authority publishes for e-Invoice lines: 45 codes from 001 (Breastfeeding equipment) to 045 (Self-billed – non-monetary payment to agents, dealers or distributors), under one type, MALAYSIA-EINVOICE. The list is seeded into every tenant by the platform; every one of the 90 tenants has exactly these 45 rows and no tenant has added a second type, although the screen lets you add a row. The combination of code, type and status is unique.

An item’s classification is three columns on its header — the list row’s guid, its code and its description — set on the item’s E-Invoice tab, or inherited from a category’s e-Invoice defaults or from a template when the field is empty. One behaviour of that tab to know about: if the item has no classification and no template or category supplies one, opening the E-Invoice tab pre-fills 022 – Others and treats it as a change. It is a convenience for accessories; it is wrong for a smartphone, and it is silent, so check the field rather than trusting the pre-fill.

A document line carries its own copy of the code and description, and at submission the rule is: the line’s own classification is used; if the line has none, the item’s; if neither, the line goes out without one — and classification is a mandatory field on an LHDN e-Invoice line. For a retailer the code is almost always 003 (Computer, smartphone or tablet) for the hardware, 022 (Others) for accessories that fit nothing else, and 044 (Vouchers, gift cards, loyalty points) for gift cards. 66 of the 81 tenants with items have classified them; on average four items in five carry a code. The rest is the source of “submitted without classification” rejections.

Before you start

  • You are editing items in the Doc Item Maintenance applet and have the permission set that includes API_TNT_DM_ITEM_COMPANY_GLCODE_LINK_CREATE (the applet’s OWNER or ADMIN roles have it).
  • The item is already linked to the company on the Company Linking tab — the GL Codes tab lives inside that link, so an item GSO cannot see cannot be given GSO accounts.
  • The GL codes you want to post to exist in the company’s chart: for GadgetSphere, SALES-ONLINE-GSO and COST-SMARTPHONE in GSO’s chart, SALES-SMARTPHONE-KV01 in GS’s. See the Chart of Accounts setup guide.
  • You have one test invoice you can post and void in each company.

Step 1: Give the item its accounts in each company

By the end of this step, a sale of SP-FLAG-256 by GSO posts to SALES-ONLINE-GSO and a purchase of it by either company posts to COST-SMARTPHONE, without anyone picking a GL code on the invoice.

Doc Item Maintenance → Items → open SP-FLAG-256 → Company Linking tab → open the GSO link → GL Codes tab.

You see six dropdowns, each filtered to GSO’s chart:

Screen labelTransaction code storedUsed when
Sales/Revenue GL CodeSALESThe item is sold by GSO
Sales/Revenue Return GL CodeSALES_RETURNA GSO customer returns it
Sales/Revenue Discount CodeSALES_DISCOUNTNever read by posting today — leave empty
Purchase/Expenses GL CodePURCHASEGSO buys it
Purchase/Expenses Return GL CodePURCHASE_RETURNGSO returns it to the supplier
Purchase/Expenses Discount CodePURCHASE_DISCOUNTNever read by posting today — leave empty

Pick SALES-ONLINE-GSO for the first, SALES-ONLINE-GSO for the return (a return credits the same account), COST-SMARTPHONE for the purchase and the purchase return. Save. Behind the scenes the screen writes one link row per dropdown — four with your codes and two empty ones for the discount fields — and on a later visit it updates the rows in place.

Repeat for the GS link with SALES-SMARTPHONE-KV01 and COST-SMARTPHONE. If you have 400 smartphone SKUs to do, use Import Item → Doc Item With GL Code instead. Despite the name, this import is exactly these links: its template has five columns — ITEM_CODE, COMPANY_CODE, CHART_OF_ACCOUNT_CODE, GL_CODE, TXN_CODE — one row per item, company and transaction code, and TXN_CODE must be one of the six codes above or the row fails with TXN_CODE_IS_NOT_VALID. The import matches an existing row on all four keys, so re-importing the same code is idempotent, but importing a different code for the same item, company and transaction code adds a second row rather than replacing the first — delete the old one first.

The most common failure: the sale still posts to the company default. Nine times out of ten the invoice header carries a GL code (a template or a default selection put it there), and the header beats the item link. Open the posted invoice, look at the header’s GL code field, and clear it on the template.

Step 2: Put a picture on the item

Doc Item Maintenance → Items → open the item → Manage Media tab → upload.

Tick public if the web store or a marketplace listing should be able to show it — that is what sets PUBLIC_READ_ONLY and makes the public URL work. Leave it unticked for internal reference shots. There is no primary-image flag and no reliable ordering; if your storefront needs a specific hero image, set it on the storefront side.

The most common failure: the picture shows in BigLedger and not on the listing. It was uploaded without public, or it went in as an attachment (an extension row) rather than an image. Re-upload it on Manage Media with public ticked.

Step 3: Check the classification before the first e-Invoice

Doc Item Maintenance → Items → open the item → E-Invoice tab → Item classification.

For SP-FLAG-256 choose 003 – Computer, smartphone or tablet. To do a whole category at once, set the category’s e-Invoice defaults; items created under it inherit the code, and the E-Invoice tab fills it in for existing items whose field is empty when you open them. Then run the e-Invoice discrepancies report after the first day’s submissions — an item without a classification produces a rejected line, not a warning at save time.

What success looks like

Post one GSO cash bill for SP-FLAG-256 (no GL code on the header or line) and open its journal: the revenue line is SALES-ONLINE-GSO. Post one GS invoice for the same item: SALES-SMARTPHONE-KV01. Post a GSO purchase invoice for it: COST-SMARTPHONE. On the item, the Manage Media tab shows the picture with public on, and the E-Invoice tab shows 003. Void the three test documents. Five minutes.

Common mistakes

MistakeWhat you seeFix
Setting GL codes on the item’s Main tab and expecting them to differ per companyEvery company posts to the same accountThe Main-tab GL code is the item’s single code (used by Account Code items). Per-company accounts live on the Company Linking → GL Codes tab
A GL code on the document headerThe item link is ignored on every line of that documentClear the header GL code on the document template; the header beats the item link
Filling the Discount GL code fieldsNothing happensPosting never reads SALES_DISCOUNT / PURCHASE_DISCOUNT links today. Discounts post through the company default
Two link rows for the same item, company and code (after an import with a new code)The account changes from one invoice to the nextList the links (GET …/item-company-glcode-links/query), delete the older row; keep one row per code
Track inventory left unticked at createThe item never appears in stock balance; a stock-out document line for it moves nothingOpen the item on the Edit screen, tick Track inventory and save — the Edit screen’s save creates the stock record when the item has none. Confirm it exists in the Inventory Item Maintenance applet before selling the item
Image uploaded as an attachment, or without publicPicture visible in BigLedger, missing on the listingRe-upload on Manage Media with public ticked
No classification on the item or the linee-Invoice line rejected by LHDNSet it on the item or its category; re-submit
Opening the E-Invoice tab of an unclassified item and savingThe item is now 022 – Others, whatever it isThe tab pre-fills 022 when nothing else supplies a code. Pick the right code before you save

Related documentation